Обобщения - Открытые и закрытые построенные типы - PullRequest
47 голосов
/ 14 ноября 2009

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

Ответы [ 3 ]

66 голосов
/ 14 ноября 2009

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

  • Для типа unbound не заданы аргументы типа
  • A сконструированный тип имеет по крайней мере один аргумент типа, указанный
  • Параметр типа открытый тип
  • Тип массива с открытым типом элемента - открытый тип
  • открытый составной тип имеет по крайней мере один аргумент типа, который является открытым типом
  • A закрытый тип - любой тип, который не открыт

(Есть дополнительные правила для вложенных типов. Обратитесь к разделу 4.4 спецификации C # 3.0 за подробностями.)

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

public class NameDictionary<T> : Dictionary<string, T>

Базовый класс typeof(NameDictionary<>):

  • Создано, поскольку оно определяет аргументы типа
  • Открыть, поскольку второй тип аргумента (T) является открытым типом

Документы MSDN для Type.IsGenericType имеют довольно полезный столик.

Просто повторюсь, это практически неважно при повседневном использовании.

Я обычно за то, чтобы знать правильную терминологию - особенно для таких вещей, как «передача по ссылке» и т. Д. - но в этом случае это действительно, действительно, не очень часто встречается. Я хотел бы активно отговорить вас от беспокойства об этом:)

7 голосов
/ 14 ноября 2009

С MSDN :

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

Так что это работает как List<int> закрыто :

var list = Activator.CreateInstance(typeof(List<int>));

Но это вызывает исключение во время выполнения, потому что List<> - это open :

var list = Activator.CreateInstance(typeof(List<>));
                                               ↑
3 голосов
/ 14 ноября 2009

Я в основном использовал открытые дженерики (в основном неопознанные дженерики) в отображениях внедрения зависимостей. Например, что-то вроде

Bind<IRepository<>>()
   .To<BasicRepository<>>()

Тогда, когда мой конструктор объекта содержит:

public SomethingController(IRepository<Something>) { ... }

Мой механизм внедрения зависимостей автоматически создаст экземпляр BasicRepository . (Это работает с Ninject и StructureMap и, возможно, с библиотекой Castle Windsor; я не уверен насчет других фреймворков).

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