非静态字段、方法或属性需要对象引用
本文关键字:属性 对象引用 方法 静态 字段 | 更新日期: 2023-09-27 18:13:59
我知道以前有人问过这个问题,但是这个场景太具体了,我对基本原理感到困惑。
我有两个基本版本的c#程序,一个可以工作,一个不能。如果有人能解释一下为什么我得到错误在第二个程序中非静态字段、方法或属性需要对象引用,我将很高兴。
:
namespace Experiments
{
class Test
{
public string myTest = "Gobbledigook";
public void Print()
{
Console.Write(myTest);
}
}
class Program
{
static void Main(string[] args)
{
Test newTest = new Test();
newTest.Print();
while (true)
;
}
}
}
不工作:
namespace Experiments
{
class Test
{
public string myTest = "Gobbledigook";
public void Print()
{
Console.Write(myTest);
}
}
class Program
{
public Test newTest = new Test();
static void Main(string[] args)
{
newTest.Print();
while (true)
;
}
}
}
当我在第二个程序中尝试Print()来自Test()类的文本时,它给了我错误非静态字段,方法或属性需要对象引用,我不明白为什么。我可以看出这与我在哪里声明Test()类的实例有关,但我不记得在c++中发生过这样的事情,所以我很困惑。
怎么回事?
这并不是因为类的定义,而是关键字static
的使用。
类Test
的newTest
对象是类Program
的公共成员,main
是程序类内部的静态函数。并且在错误信息An object reference is required for the non-static method
中明确提到。因此,您需要的是将newTest
对象声明为静态,以便在静态方法(如main)中访问它们。
public static Test newTest = new Test();
一个附加注释
考虑在类Test
中定义方法Print
为static
,如下所示:
public static void Print()
{
Console.Write(myTest);
}
那么你就不能像你目前使用的那样调用方法(newTest.Print();
)。您必须使用Test.Print();
,因为静态成员不能通过实例引用。相反,它是通过类型名称引用的。例如,考虑下面的类
在第一个程序中,您在static方法中创建了一个新实例。在这个方法中可以做任何事情。
但是当你想调用静态方法之外的一些方法或访问一些变量时,你需要它们是静态的。原因是当您调用静态方法时,没有创建类的实例,因此还没有创建非静态变量的实例,您无法访问它们!
因此,在第二个程序中,直到在 program 类(如Program p = new Program();
)之外有一些代码行,才执行newTest变量初始化行。解决方案是使变量静态,以便能够在静态Print()方法之外访问它,或者您可以将Min()方法转换为非静态模式,这对于Main()方法是不可能的。
如果你想定义一个全局变量,那么我建议你定义一个特殊的类,例如MyGlobals:
public class SomeClass
{
public int x;
}
public class MyGlobals
{
public static SomeClass mySharedVariable = new SomeClass();
public SomeClass myGlobalVariable = null;
}
// Usage:
class Program
{
static void Main(string[] args)
{
MyGlobals.mySharedVariable.x = 10; // Shared among all instances
MyGlobals myGlobal = new MyGlobals(); // New instance of MyGlobals
myGlobal.myGlobalVariable = new SomeClass(); // New instance of SomeClass
myGlobal.myGlobalVariable.x = 10; // One instance of MyGlobals including one instance of SomeClass
}
}