Каковы причины дизайна, чтобы запретить доступ к статическим элементам класса через объект - PullRequest
4 голосов
/ 25 августа 2011

Я не могу подчеркнуть это больше - причины дизайна .

В C ++ вы можете получить статический элемент, используя ссылку на класс (тип) или ссылку на объект (экземпляр). В C # только ссылка на тип. Чем больше я пишу в C #, тем больше проблем это вызывает - есть просто моменты (снова и снова), что все, что у меня есть, это объект, и чтобы избежать проблемы с отсутствием типа (и, следовательно, доступа к статическому элементу), создавая обычный элемент, который передает значения назад и вперед к статическому элементу.

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

Каковы причины проектирования, в C # вы не можете ссылаться на статический элемент объекта (конечно, извне)?

Пример кода

public class Foo
{
   public static readonly string Name = "name";
}

...

Foo foo = new Foo();

и теперь рассмотрим "Foo.Name" против "foo.Name";

Пример реального случая

Одним из наиболее используемых для меня классов является ассоциативный массив (мой пользовательский класс) для перечислений - AssocEnum. Это как словарь, но все ключи предварительно заполнены. Помимо этого у меня есть классы, такие как EnumBit (который является AssocEnum) и EnumNames (который является AssocEnum). В отличие от словаря, каждый экземпляр give enum имеет одно и то же свойство Keys. Это означает, что вы можете получить ключи для типа AssocEnum и его экземпляра.

Меня беспокоит тот факт, что мне нужно ввести два свойства TypeKeys (для класса) и Keys (например, который является просто прокси-сервером TypeKeys) только потому, что я не могу вызвать статические TypeKeys для экземпляра AssocEnum.

Ответы [ 2 ]

9 голосов
/ 25 августа 2011

IMO «причина замысла» здесь частично связана с очевидностью намерения. Вот классический пример:

Thread someOtherThread = GetAnotherThread();
someOtherThread.Sleep();

сейчас; какая нить только что пошла спать? Thread.Sleep() - статический метод; он влияет только на поток current . Но наш код предположил (совершенно неверно), что мы вызвали метод, относящийся к конкретному экземпляру (someOtherThread).

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

В качестве другого примера:

Control someControl = GetSomeRandomControl();
someControl.CheckForIllegalCrossThreadCalls = false;

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

Таким образом:

Thread.Sleep():

и

Control.CheckForIllegalCrossThreadCalls = false;

гораздо яснее выразить то, что они делают.

1 голос
/ 25 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...