2016-10-20 3 views
4

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

У меня есть две базовые версии программы 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() класса во второй программе, это дает me, что ошибка Ссылка на объект требуется для нестатического поля, метода или свойства, и я не понимаю, почему. Я вижу, что это связано с тем, где я объявляю экземпляр класса Test(), но я не помню ничего подобного в C++, поэтому меня это озадачивает.

Что происходит?

ответ

3

Это не из-за определения класса, это все об использовании ключевого слова static.

newTest объект класса Test является публичным членом класса Program и main статическая функция внутри класса программы. и это сговор, упомянутое в сообщении об ошибке An object reference is required for the non-static method. Итак, вам нужно объявить объект newTest статическим для доступа к ним в статических методах, таких как main.

как это

public static Test newTest = new Test(); 

Дополнительное примечание

Считают, что вы Ware определить метод Print, как static внутри класса Test, как следующий вид:

public static void Print() 
{ 
    Console.Write(myTest); 
} 

Тогда вам не можете вызвать метод, как то, что вы используете в данный момент (newTest.Print();). Вместо этого вы должны использовать Test.Print();, так как Статический член нельзя ссылаться через экземпляр. Вместо этого на него ссылаются через имя типа. Например, рассмотрим следующий класс:

+0

не создает статический переменные плохую практику, кроме как в исключительных случаях, так же, как – Simflare

+0

продолжал предыдущим - так же, как глобальные переменные не рекомендуются в C++? – Simflare

+0

Спасибо за ваш хорошо продуманный ответ btw :) – Simflare

0

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

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

Таким образом, во второй программе переменная инициации линии newTest не выполняется до тех пор, пока есть некоторые строки кода за пределами программы класса как Program p = new Program();. Решение заключается в том, что вы ставите переменную static для доступа к ней за пределами статического метода Print(). Или вы можете преобразовать свой метод Min() в нестатический режим, который невозможно для Main() метод исключительно.

Если вы хотите определить глобальную переменную, то я предлагаю вам определить специальный класс e.x. 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 
    } 
} 
+0

Спасибо, что это полезное объяснение. Это немного отличается от того, как я привык использовать слово static в C++. Не будет ли обескураживать статическую переменную, так же как и глобальные переменные в C++? – Simflare

+0

Я отредактировал свой ответ, чтобы показать способ определения глобальных переменных в C#. Повторите мой ответ. Я надеюсь быть полезной для вас. – Amin

+0

Спасибо, что нашли время поделиться этим :) – Simflare

Смежные вопросы

 Смежные вопросы