Почему я могу получить доступ только к статическим членам из статической функции? - PullRequest
13 голосов
/ 17 февраля 2010

У меня есть статическая функция в классе.

всякий раз, когда я пытаюсь использовать нестатический элемент данных, я получаю следующую ошибку компиляции.

Ссылка на объект требуется для нестатического поля, метода или элемента свойства

Почему он так себя ведет?

Ответы [ 6 ]

19 голосов
/ 17 февраля 2010

Нестатический член принадлежит экземпляру. Это бессмысленно без какого-либо решения, о каком экземпляре класса вы говорите. В статическом контексте у вас нет экземпляра, поэтому вы не можете получить доступ к нестатическому члену без явного упоминания ссылки на объект.

Фактически, вы можете получить доступ к нестатическому члену в статическом контексте, явно указав ссылку на объект:

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?

5 голосов
/ 17 февраля 2010

Методы экземпляра зависят от состояния этого конкретного экземпляра для запуска.

Допустим, у вас был этот класс с описанным вами сценарием:

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

    private Name { get; set; }
}

Надеюсь, проблема сейчас очевидна. Поскольку Name является экземпляром члена, вам нужен фактический экземпляр класса, так как Name может отличаться в разных экземплярах.

Из-за этого статический метод, который не привязан к экземпляру, не знает какой экземпляр использовать. Вы должны четко указать, какой именно.

2 голосов
/ 17 февраля 2010

Статические функции могут использовать только статические члены и вызывать статические функции.

Как уже упоминалось, статическая функция может работать на экземпляре класса, но не с в экземпляре класса (из-за отсутствия более описательного слова). Например:

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)
    }
}
2 голосов
/ 17 февраля 2010

Статический метод не может получить прямой доступ к любым нестатическим переменным-членам класса.

В конце концов: статический метод может быть вызван, даже если экземпляр класса не существует. Как вы хотите получить доступ к переменной-члену на несуществующем экземпляре ??

(конечно, как отметил Мерад: вы можете передать экземпляр вашего класса статическому методу и получить доступ ко всему в этом экземпляре - но это не то, о чем вы говорите, верно?)

1 голос
/ 17 февраля 2010

Определение "нестатического элемента данных" будет "экземпляром элемента данных". Другими словами, нестатические члены принадлежат созданному экземпляру вашего класса.

Статический метод не запускается в контексте какого-либо конкретного экземпляра класса. Следовательно, когда вы попросите такой метод использовать нестатический член, он не будет знать, из какого 0 или более экземпляров класса ему следует пытаться получить данные.

1 голос
/ 17 февраля 2010

Вы не можете получить доступ к нестатическим данным из статической функции. Это связано с тем, что статическая функция может вызываться независимо от того, существуют ли какие-либо экземпляры объекта класса. Однако нестатические данные зависят от конкретного объекта (создания экземпляра) класса. Поскольку вы не можете быть уверены, что есть какие-либо объекты, созданные при вызове статической функции, нелогично (и, следовательно, не разрешено) получать доступ к нестатическим данным из нее.

Этот вопрос был задан несколько раз на SO в разных формах / для разных языков:

...