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

时间:2010-02-17 18:17:01

标签: c# static-methods

我在课堂上有静态功能。

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

非静态字段,方法或属性成员

需要对象引用

为什么表现得那样?

6 个答案:

答案 0 :(得分:19)

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

事实上,您可以通过明确指定对象引用来访问静态上下文中的非静态成员:

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?

答案 1 :(得分:5)

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

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

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

    private Name { get; set; }
}

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

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:2)

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

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

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)
    }
}

答案 4 :(得分:1)

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

这个问题已经多次以不同形式/不同语言提出过:

答案 5 :(得分:1)

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

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