Reputation: 597
i'm working with PHP code and i have not much experienced with C#, i modified my code a lot, but still experiencing error "A field initializer cannot reference the non-static field, method, or property" at line number 34 Why it happens always and how to fix it?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Finisar.SQLite;
namespace Stemmer
{
class ValueObj
{
public void postfix(string table)
{
SQLiteConnection sqlite_conn;
SQLiteCommand sqlite_cmd;
SQLiteDataReader sqlite_datareader;
sqlite_conn = new SQLiteConnection("Data Source=database.db;Version=3;New=False;Compress=True;");
sqlite_conn.Open();
sqlite_cmd = sqlite_conn.CreateCommand();
sqlite_cmd.CommandText = "SELECT * FROM " + table;
sqlite_datareader = sqlite_cmd.ExecuteReader();
List<string> list = new List<string>();
while (sqlite_datareader.Read())
{
list.Add(sqlite_datareader.GetString(1));
}
return list.ToArray(); // returns void, a return keyword must not be followed by an object expression
}
public string[] postfixList = postfix("postfixList"); // A field initializer cannot reference the non-static field, method, or property
}
}
Upvotes: 1
Views: 1438
Reputation: 8782
In C# it is not valid to initialize a non-static field with a method. If you are using Visual Studio it should highlight the postfix
method in this line:
public string[] postfixList = postfix("postfixList");
If you need to use a method you have to move the initialization to the constructor.
public string[] postfixList;
public ValueObj()
{
postfixList = postfix("postfixList");
}
When initializing at the declaration time what's allowed is to use a value for a value type, e.g.:
public int myLuckyNumber = 13;
or if initializing a reference type you can create a new instance of the type:
public MyClass myField = new MyClass();
In this thread you can find more suggestions to what's best practice when initializing a field in C#.
Not related to the question but note that in C# preferred formatting convention is to use camel cases and start the name of a method with a capital letter.
Upvotes: 2
Reputation: 5075
There are many errors in your code.
Also postfixList is not a static property. It means that It will only be initialized once the class ValueObj has been initialized.
The problem is in a class life cycle, class properties don't exists until the object is created(unless static). In your case when you create an object valueOBJ FIRST it tries to initialize all the properties, then it calls the class constructor. Your property postfixList tries to call a class method that has not been constructed yet.
If you want it to look like a c# code do it like this:
public class ValueObj{
private string[] _postfixList;
public string[] PostfixList{ get{
if(_postFixList == null){
_postFixList = postfix("postfixList")
}
return _postfixList
}}
}
Upvotes: 1
Reputation: 30813
The field initializer has to be assigned without the instance
of the class
.
You got that error because your:
public string[] postfixList = postfix("postfixList");
Assumes the ValueObj
class
instance already exists and call postfix
(as postfix
is part of the instance
of the ValueObj
class
, not part of the ValueObj
class
) while in fact it has not existed yet on the time of calling.
There are two ways to solve this, one way is by initializing postfix
in the constructor (which the other answer shows).
And as an alternative answer besides initializing postfix
in the ValueObj
constructor, if your postfix
method is going to be the same for all ValueObj
instances, you may as well declare it as static
and return string[]
as follow:
class ValueObj
{
public static string[] postfix(string table) //note the static and string[]
{
SQLiteConnection sqlite_conn;
SQLiteCommand sqlite_cmd;
SQLiteDataReader sqlite_datareader;
sqlite_conn = new SQLiteConnection("Data Source=database.db;Version=3;New=False;Compress=True;");
sqlite_conn.Open();
sqlite_cmd = sqlite_conn.CreateCommand();
sqlite_cmd.CommandText = "SELECT * FROM " + table;
sqlite_datareader = sqlite_cmd.ExecuteReader();
List<string> list = new List<string>();
while (sqlite_datareader.Read())
{
list.Add(sqlite_datareader.GetString(1));
}
return list.ToArray(); // returns string[]
}
public string[] postfixList = postfix("postfixList"); // now it is ok
}
Upvotes: 2
Reputation: 8111
Create a constructor and assign the field there:
public string[] postfixList;
public ValueObj()
{
postfixList = postfix("postfixList");
}
And the returntype of postfix
method must be string[]
and not void
The field postfixList
is an instance member of the class and is not static. The call to postfix()
is outside a method and so is static. If you call it within the constructor, it is called each time when the class is instantiated.
For the difference between static
and instance
members, please refer for example to https://msdn.microsoft.com/aa645629(v=vs.71).aspx
Upvotes: 3