Глобальные переменные v Настройки в C#

Я добавлю свою речь к шуму и попробую ясно давать понять вещи:

Дженерики C# позволяют Вам объявлять что-то вроде этого.

List<Person> foo = new List<Person>();

и затем компилятор будет препятствовать тому, чтобы Вы поместили вещи, которые не являются Person в список.
Негласно компилятор C# просто помещает List<Person> в.NET dll файл, но во времени выполнения JIT-компилятор идет и создает новый набор кода, как будто Вы записали специальный класс списка только для содержания людей - что-то как ListOfPerson.

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

оборотная сторона этого - то, что старый C# 1.0 и 1,1 кода (прежде чем они добавили дженерики) не понимают эти новые List<something>, таким образом, необходимо вручную преобразовать вещи назад в простой List для взаимодействия с ними. Это не является настолько большим из проблемы, потому что двоичный код C# 2.0 не назад совместим. Единственное время это будет когда-либо происходить, - то, при обновлении некоторого старого C# 1.0/1.1, код к дженерикам C# 2.0

Java позволяют Вам объявлять что-то вроде этого.

ArrayList<Person> foo = new ArrayList<Person>();

На поверхности это выглядит одинаково, и это, вид-. Компилятор будет также препятствовать тому, чтобы Вы поместили вещи, которые не являются Person в список.

различие - то, что происходит негласно. В отличие от C#, Java не идет и создает специальное предложение ListOfPerson - это просто использует простое ArrayList, который всегда был в Java. Когда Вы вытаскиваете вещи из массива, обычное Person p = (Person)foo.get(1);, танец кастинга все еще должен быть сделан. Компилятор сохраняет Вас нажатия клавиш, но хит/кастинг скорости все еще понесен точно так же, как это всегда было.
, Когда люди упоминают "Стирание Типа", это - то, о чем они говорят. Компилятор вводит броски для Вас, и затем 'стирает' то, что он предназначен, чтобы быть списком Person не всего Object

, преимущество этого подхода - то, что старый код, который не понимает дженериков, не должен заботиться. Это все еще имеет дело с то же старое ArrayList, как это всегда имеет. Это более важно в мире Java, потому что они хотели поддерживать код компиляции с помощью Java 5 с дженериками, и работая на нем старые 1.4 или предыдущая JVM, которой Microsoft сознательно решила не обеспокоиться.

оборотная сторона является хитом скорости, который я упомянул ранее, и также потому что нет никакого ListOfPerson псевдокласс или что-либо как этот вход в .class файлы, кодируйте, который смотрит на него позже (с отражением, или если Вы вытаскиваете его из другого набора, где это было преобразовано в [1 121], или так на) не может сказать всегда, что это предназначено, чтобы быть списком, содержащим [только 1 122] и не только любой другой список массива.

Шаблоны C++ позволяют Вам объявлять что-то вроде этого

std::list<Person>* foo = new std::list<Person>();

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

Это имеет большинство вместе с дженериками C#, в которых это создает особенный pseudo-classes вместо того, чтобы просто выбросить информацию о типе как Java, делает, но это - целое другое дело.

И C# и Java производят вывод, который разработан для виртуальных машин. Если Вы запишете некоторый код, который имеет Person класс в нем, в обоих случаях некоторая информация о Person, то класс войдет в .dll или .class файл, и JVM/CLR сделает материал с этим.

C++ производит сырые данные x86 двоичный код. Все не объект, и нет никакой базовой виртуальной машины, которая должна знать о Person класс. Нет никакой упаковки или распаковывания, и функции не должны принадлежать классам, или действительно чему-либо.

из-за этого, компилятор C++ не устанавливает ограничений для того, что можно сделать с шаблонами - в основном любой код, который Вы могли записать вручную, можно заставить шаблоны писать для Вас.
самый очевидный пример добавляет вещи:

В C# и Java, система дженериков должна знать, какие методы доступны для класса, и это должно передать это к виртуальной машине. Единственный способ сказать его это или жестким кодированием фактический класс в или использующими интерфейсами. Например:

string addNames<T>( T first, T second ) { return first.Name() + second.Name(); }

, Что код не скомпилирует в C# или Java, потому что это не знает, что тип T на самом деле предоставляет метод под названием Имя (). Необходимо сказать его - в C# как это:

interface IHasName{ string Name(); };
string addNames<T>( T first, T second ) where T : IHasName { .... }

И затем необходимо удостовериться вещи, Вы передаете реализации addNames интерфейс IHasName и так далее. Синтаксис Java отличающийся (<T extends IHasName>), но он страдает от тех же проблем.

'классический' случай для этой проблемы пытается записать функцию, которая делает это

string addNames<T>( T first, T second ) { return first + second; }

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

C++ не страдает ни от одной из этих проблем. Компилятор не заботится о передаче типов ни к какому VM's - если оба Ваших объекта будут иметь.Name () функция, это скомпилирует. Если они не сделают, это не будет. Простой.

Так, там у Вас есть он:-)

6
задан Andy 29 October 2009 в 18:52
поделиться

5 ответов

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

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

15
ответ дан 8 December 2019 в 12:21
поделиться

В C # вам будет трудно идти против хорошего объектно-ориентированного дизайна, потому что вы не можете уйти от объектно-ориентированного проектирования. Это не похоже на C ++, где вы можете смешивать и сочетать структурированное и объектно-ориентированное программирование - область, в которой часто возникают такие аргументы. Статические члены класса - объектно-ориентированные. То же самое и с настройками, сгенерированными Microsoft, потому что генерация кода создает для них объектно-ориентированную инкапсуляцию или, по крайней мере, «объект-контейнер» вокруг них. Таким образом, они никогда не являются глобальными переменными, потому что этого не существует в C # - они просто статические члены в классах - ничего, что не было бы OO.

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

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

2
ответ дан 8 December 2019 в 12:21
поделиться

Открытый статический класс или член - не всегда плохая идея (даже если это не совсем объектно-ориентированный подход). Многие хорошие проекты OO используют общедоступный статический член для таких вещей, как Регистраторы или Настройки (как вы указываете). Хорошим примером того, как это сделать объектно-ориентированным способом, является Static Gateway .

1
ответ дан 8 December 2019 в 12:21
поделиться

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

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

1
ответ дан 8 December 2019 в 12:21
поделиться

Механизм настроек ... хм ...

Я смотрю на них в основном как на часть среды. Вроде ОС или Времени, но для приложения. На самом деле они не являются «переменными», которые вы объявляли бы во время INIT.

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

В конце концов, по мере развития приложений, такие вещи все равно оборачиваются вокруг них. Мое правило: всякий раз, когда я начинаю думать: «Нет, это слишком просто, слишком атомарно и не требует объекта ...» - вот мой ключ к тому, чтобы сделать его объектом.

0
ответ дан 8 December 2019 в 12:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: