Ahmed iqbal
Ahmed iqbal

Reputation: 597

C# Error: A field initializer cannot reference the nonstatic field method or property

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

Answers (4)

PiotrWolkowski
PiotrWolkowski

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

Stralos
Stralos

Reputation: 5075

There are many errors in your code.

  1. class ValueObj should be public class ValueObj. Yes a class can be private in c#
  2. public void postfix(string table){...} returns void. It means that a function doesnt return a thing. You cant use it to set value to public string[] postfixList. It should return an array of string.

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

Ian
Ian

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

Flat Eric
Flat Eric

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

Related Questions