2016-01-23 55 views
1

我正在使用PHP代码,并且我没有太多的C#经验,我修改了我的代码很多,但仍然遇到错误“字段初始值设定项不能引用非静态字段,方法或属性“在行号为什么它总是发生并且如何解决它?C#错误:字段初始值设定项不能引用非静态字段方法或属性

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 

    } 
} 
+0

哪里是第34行? – Stralos

+0

public string [] postfixList = postfix(“postfixList”); –

+1

C#不是PHP。它实际上很锋利。 –

回答

3

创建一个构造函数,并分配有现场:

public string[] postfixList; 

public ValueObj() 
{ 
    postfixList = postfix("postfixList"); 
} 

而且postfix方法的返回类型必须是string[]而不是void

领域postfixList是类的实例成员,不是静态的。对postfix()的调用不在方法之内,因此是静态的。如果你在构造函数中调用它,每次类实例化时都会调用它。

对于staticinstance部件之间的差,请参考例如,以https://msdn.microsoft.com/aa645629(v=vs.71).aspx

+0

你回答了问题的一部分。你也应该解释为什么OP得到错误。 –

+0

非常感谢,非常有帮助的信息 –

2

该字段初始具有未经classinstance进行分配。

你明白我的错误,因为你:

public string[] postfixList = postfix("postfixList"); 

假设ValueObjclass实例已经存在,并调用postfix(为postfixValueObjclass,而不是ValueObjclass的部分instance的一部分),而在实际上它在通话时还没有存在。

有两种方法可以解决这个问题,一种方法是在构造函数中初始化postfix(其他答案显示)。

而作为除了在ValueObj构造函数初始化postfix的备选答案,如果你的postfix方法将是所有ValueObj实例一样,你不妨将它声明为staticreturn string[]如下:

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 

} 
+0

非常快速和简单的解决方案。谢谢亲爱的 –

+0

@Ahmediqbal是的,它是。 ;)但请注意我的评论:只要所有实例使用'postfix'完全相同,此解决方案就很好。既然你在初始化中用常量输入'postfixList'来使用它,我假定它是。 ;)如果在您的开发过程中的某一点,这是停止的情况下,请考虑其他答案。 :) – Ian

+0

构造函数解决方案也适用于我,我混淆了哪一个我的选择:( –

1

你的代码有很多错误。

  1. class ValueObj应该是公共类ValueObj。是的,一个类可以是 私有的c#
  2. public void postfix(string table){...}返回void。这意味着一个 函数不会返回一个东西。你不能用它来设置值为 public string [] postfixList。它应该返回一个字符串数组。

此外,postfixList不是一个静态属性。这意味着只有在ValueObj类被初始化后才会初始化它。

问题出在类生命周期中,直到创建对象(除非是静态),类属性才会存在。在你的情况下,当你创建一个对象valueOBJ FIRST时,它会尝试初始化所有属性,然后调用类构造函数。你的属性postfixList尝试调用尚未构造的类方法。

如果你希望它看起来像一个C#代码做这样的:

public class ValueObj{ 

    private string[] _postfixList; 

    public string[] PostfixList{ get{ 
     if(_postFixList == null){ 
      _postFixList = postfix("postfixList") 
     } 
     return _postfixList 
    }} 
} 
+0

你是对的,谢谢你的回答 –

2

在C#中它是无效的初始化非静态字段的方法。如果您在使用Visual Studio,应该突出postfix方法在这条线:

public string[] postfixList = postfix("postfixList"); 

如果你需要使用你必须初始化移动构造函数的方法。

public string[] postfixList; 
public ValueObj() 
{ 
    postfixList = postfix("postfixList"); 
} 

当在所允许的声明时初始化是使用值的值类型,例如:

public int myLuckyNumber = 13; 

,或者初始化引用类型,你可以创建类型的新实例:

public MyClass myField = new MyClass(); 

this thread你可以找到更多的建议,在C#中初始化场时,什么是最好的做法。

与问题无关,但请注意,在C#首选格式约定是使用骆驼案件,并用大写字母开始方法的名称。

+0

感谢分享:) –

相关问题