Проблема вложенного типа - PullRequest
7 голосов
/ 22 марта 2011

Я только что попытался создать эту простую реализацию:

class Test
{
   private int abc = 0;

   public class TestClass
   {
      private void changeABC()
      {
         abc = 123;
      }
   }
}

Если я скомпилирую, он будет жаловаться:

Невозможно получить доступ к нестатическому члену внешнего типа «A.Test» через вложенный тип «B.Test.TestClass»

Мне не нравится решение настройки: static int abc = 0;

Есть ли другое решение для этого?

Ответы [ 4 ]

15 голосов
/ 22 марта 2011

Вы, вероятно, пришли из Java-фона, где этот код будет работать как положено.

В C # вложенными типами являются static (на языке Java), т. Е. Они не привязаны к экземпляру родительского класса. Вот почему ваш код не работает. Вам нужно как-то передать экземпляр родительского класса дочернему классу и получить доступ к его члену abc.

8 голосов
/ 22 марта 2011

Внутреннему классу нужна ссылка на экземпляр внешнего класса:

class Test
{
   private int abc = 0;

   public class TestClass
   {
      private void changeABC(Test test)
      {
         test.abc = 123;
      }
   }
}
1 голос
/ 22 марта 2011

Из C # вложенные классы похожи на вложенные классы C ++, а не внутренние классы Java

Когда вы объявляете класс внутри другого класса, внутренний класс по-прежнему действует как обычный класс,Вложенность контролирует доступ и видимость, но не поведение.Другими словами, все правила, которые вы узнали о обычных классах, также применяются к вложенным классам.

В Java внутренний класс имеет секретный член this $ 0, который запоминает экземпляр внешнего класса, с которым он был связан.

Другими словами, внутренние классы Java являются синтаксическим сахаром, недоступным для C #.В C # вы должны сделать это вручную.

1 голос
/ 22 марта 2011

Я не понимаю, почему TestClass должен изменить родителя Test, когда это класс экземпляра.

Может быть, мой пример пролил бы свет на это:

class Test
{
   public Test()
   {
     TestClass test = new TestClass();//create a new **instance** here
     test.changeABC(this);//give the instance of Test to TestClass
     Console.WriteLine(abc);//will print 123 
   }
   int abc = 0;

   public class TestClass
   {
      public void changeABC(Test t)
      {
         t.abc = 123;
      }
   }
}

Используйте как это:

Test theTest = new Test();
...