为什么我只能从静态函数访问静态成员?

我在一个类中有一个静态函数。

每当我尝试使用非静态数据成员时,我都会遇到编译错误。

非静态字段,方法或属性成员需要对象引用

为什么它表现得那样?

非静态成员属于实例。 如果不以某种方式解决你正在谈论的课程的哪个实例,这是没有意义的。 在静态上下文中,您没有实例,这就是为什么在没有明确提及对象引用的情况下无法访问非静态成员的原因。

实际上,您可以通过显式指定对象引用访问静态上下文中的非静态成员:

class HelloWorld { int i; public HelloWorld(int i) { this.i = i; } public static void Print(HelloWorld instance) { Console.WriteLine(instance.i); } } var test = new HelloWorld(1); var test2 = new HelloWorld(2); HelloWorld.Print(test); 

如果没有明确引用Print方法中的实例,它怎么知道它应该打印1而不是2?

实例方法依赖于该特定实例的状态才能运行。

假设你有这个类,它有你描述的场景:

 class Person { static PrintName() { // Not legal, but let's say it is for now. Console.WriteLine(Name); } private Name { get; set; } } 

希望现在问题很明显。 因为Name是实例成员,所以您需要该类的实际实例,因为Name可以在不同实例之间不同。

因此,静态方法(未附加到实例)不知道要使用哪个实例。 你必须明确指定哪一个。

静态方法不能直接访问类的任何非静态成员变量。

毕竟:即使存在,也可以在没有类实例的情况下调用静态方法。 您想如何访问不存在的实例上的成员变量?

(当然,正如Mehrdad指出的那样:你可以将你的类的实例传递给静态方法并访问该实例上的所有内容 – 但这不是你所说的,对吧?)

静态函数只能使用静态成员,并调用静态函数。

如上所述,静态函数可以类实例进行操作,但不能类实例中进行操作(缺少更具描述性的单词)。 例如:

 class MyClass { public int x; public static int y; public static void TestFunc() { x = 5; // Invalid, because there is no 'this' context here y = 5; // Valid, because y is not associated with an object instance } public static void TestFunc2(MyClass instance) { instance.x = 5; // Valid instance.y = 5; // Invalid in C# (valid w/ a warning in VB.NET) } } 

“非静态数据成员”的定义将是“实例数据成员”。 换句话说,非静态成员属于您的类的已创建实例。

静态方法不会在类的任何特定实例的上下文中运行。 因此,当您要求这样的方法使用非静态成员时,它将不知道应该尝试从该类中获取数据的0个或更多实例中的哪个。

您无法从静态函数访问非静态数据。 这是因为无论是否存在类的任何实例化对象,都可以调用静态函数。 但是,非静态数据依赖于类的特定对象(实例化)。 由于在调用静态函数时无法确定是否有任何对象被实例化,因此从它访问非静态数据是不合逻辑的(因此不允许)。

关于不同forms/不同语言的SO已经多次询问过这个问题:

  • C#
  • Java的
  • python
  • PHP
  • 与语言无关