почему статический член не может быть достигнут через имя экземпляра? - PullRequest
6 голосов
/ 19 марта 2010

скажи, что у меня есть:

 class Test
 {
      public static int Hello = 5;
 }

Это, очевидно, работает:

 int j = Test.Hello;

Но почему это не должно работать?

 Test test = new Test();
 int j = test.Hello;

Экземпляр не может иметь элемент с одинаковым именем, поэтому я не понимаю, как это может быть неоднозначным или неразрешимым для компилятора.

Кто-нибудь знает, почему это так?

EDIT: Есть ли какая-либо другая техническая причина, почему это должно быть ДРУГОЙ, чем разработчики языка, выбирающие это для удобства чтения / ясности / эстетики / и т. Д.

Ответы [ 5 ]

14 голосов
/ 19 марта 2010

Другой угол:

Предположим, это было возможным. Что бы вы хотели получить в результате, когда к статическому члену обращаются через переменную экземпляра, равную null? Желаете ли вы исключение с нулевой ссылкой (но почему, поскольку для получения статического члена не требуется экземпляр)? Или вы хотели бы, чтобы это работало (в этом случае у вас возникла бы странная ситуация, когда некоторые вызовы этой переменной экземпляра работали, а некоторые нет)? В любом случае есть проблемы.

11 голосов
/ 19 марта 2010

Помните, что такое статические методы (или свойства, или поля): они принадлежат классу, а не какому-либо конкретному экземпляру этого класса. Из-за этого они являются общими для всех экземпляров.

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

1 голос
/ 19 марта 2010

«Есть ли какая-либо другая техническая причина, по которой это должно быть ДРУГОЙ, чем те, кто выбирает язык для удобства чтения / ясности / эстетики / и т. Д.?»

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

1 голос
/ 19 марта 2010

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

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

0 голосов
/ 19 марта 2010

Вы можете прочитать подробное объяснение статического ключевого слова на MSDN , но я думаю, что лучше всего объяснить эту цитату

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

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

Что касается неоднозначности имен, это может быть так же просто, как коллизия имен внутри чего-либо, например таблицы символов. Тем не менее, может быть легко провести более глубокое техническое рассмотрение.

...