2010-01-31 4 views
100

я шел через Asp.Net MVC lesson и узнал, что для метода квалифицировать как действие для контроллера,Что такое «открытый общий тип» в .NET?

  • Он не должен иметь «открыть общий тип»

Я понимаю дженерики несколько и использовать их в какой-то степени, но:

  • Что такое открыт общий тип в .Net.
  • Есть ли такая вещь, как закрытого типа типа?
  • Открытый общий тип - термин, который не используется очень часто. Что используется/путают с ним?

ответ

168

C# язык определяет открытый тип, чтобы быть типа, что это либо тип аргумента или общий тип, определенный с аргументами неизвестного типа:

Все типы могут быть классифицированы как открытого типа или закрытого типа , открытый тип - тип, который включает параметры типа. А именно:

  • Параметр типа определяет открытый тип.
  • Тип массива является открытым типом тогда и только тогда, когда его тип элемента является открытым типом.
  • A построенный тип является открытым типом тогда и только тогда, когда один или несколько аргументов своего типа являются открытым типом. A построенный вложенный тип является открытым типом тогда и только тогда, когда один или несколько аргументов своего типа или аргументы типа его содержащего типа (ов) являются открытым типом.

A закрытый тип - тип, который не является открытым.

Поэтому T, List<T> и Dictionary<string,T> и Dictionary<T,U> все открытые типы (T и U аргументы типа), тогда как List<int> и Dictionary<string,int> закрыты типов.

Существует связанная с этим концепция: несвязанный общий тип - это общий тип с аргументами неопределенного типа. Несвязанный тип не может использоваться в выражениях, отличных от typeof(), и вы не можете его создать или вызвать его методы. Например, List<> и Dictionary<,> являются несвязанными типами.

Для уточнения тонкого различия между открытым типом и несвязанным типом:

class Program { 
    static void Main() { Test<int>(); } 
    static void Test<T>() { 
     Console.WriteLine(typeof(List<T>)); // Print out the type name 
    } 
} 

Если запустить этот фрагмент кода, он будет печатать

System.Collections.Generic.List`1[System.Int32] 

который является именем CLR для List<int> , Во время выполнения ясно, что аргумент типа равен System.Int32. Это делает List<T> a связан открытый тип.

Во время выполнения, вы можете использовать отражение для связывания аргументов типа к параметрам неопределенного типа несвязанных родовых типов с Type.MakeGenericType method:

Type unboundGenericList = typeof(List<>); 
Type listOfInt = unboundGenericList.MakeGenericType(typeof(int)); 
if (listOfInt == typeof(List<int>)) 
    Console.WriteLine("Constructed a List<int> type."); 

Вы можете проверить, является ли типом является несвязанным универсальным типом (общего определения типа), из которого можно построить связанные типы с Type.IsGenericTypeDefinition property:

Console.WriteLine(typeof(Dictionary<,>).IsGenericTypeDefinition); // True 
Console.WriteLine(typeof(Dictionary<int,int>).IsGenericTypeDefinition); // False 

Чтобы получить несвязанный тип из построенного типа во время выполнения, вы можете использовать Type.GetGenericTypeDefinition method.

Type listOfInt = typeof(List<int>); 
Type list = listOfInt.GetGenericTypeDefinition(); // == typeof(List<>) 

Обратите внимание, что для универсального типа вы можете либо иметь полностью несвязанное определение типа, либо полностью связанное определение. Вы не можете связывать некоторые параметры типа и оставлять других несвязанными. Например, вы не можете иметь Dictionary<int,> или Dictionary<,string>.

+8

+1 отличная информация - сегодня я узнал что-то новое. Я знал, что List <> является общим типом, но теперь я знаю правильный технический термин. – IAbstract

+2

Вы * можете * фактически частично закрыть общий тип, предоставив аргумент типа, который сам является открытым родовым типом. Однако это тупик. Рамка официально не признает это частичное состояние, рассматривая его как закрытое, так и открытое, и поэтому оно не позволяет вам ничего полезного. –

+1

отличное объяснение различий между открытым типом и несвязанным типом - не знал раньше! – nawfal

5

«Открытый общий тип» - это всего лишь общий тип, который еще не имеет указанного типа (например, CargoCrate<T>). Он становится «закрытым» после назначения конкретного типа (например, CargoCrate<Widget>).

Например, у вас есть что-то вроде этого:

public class Basket<T> { 
    T[] basketItems; 
} 

public class PicnicBlanket<T> { 
    Basket<T> picnicBasket; // Open type here. We don't know what T is. 
} 

           // Closed type here: T is Food. 
public class ParkPicnicBlanket : PicnicBlanket<Food> { 
} 

Здесь тип picnicBasket «s открыт: ничего не еще не присвоен T. Когда вы делаете конкретный PicnicBlanket с определенным типом - например, написав PicnicBlanket<Food> p = new PicnicBlanket<Food>() - теперь мы называем это закрытым.

8

Просто добавить:

Dictionary<string, T> (точнее Dictionary<string,>) все еще открытого типа.

Пример:

void Foo<T>(Dictionary<string,T> dic) { ... } 
+0

@Mehrdad Afshari: Извините, но вы все равно можете получить то, что вы называете полузамкнутыми типами ... – leppie

+0

Кроме того, я понятия не имею, как построить это (или представлять тип), может быть, стоит вопрос. – leppie

+0

@Mehrdad Afshari: выглядит довольно открытым для меня, но я также открыт для предложений. :) – leppie

4

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

public class Dictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>> 
  • Dictionary<TKey, TValue> является неограниченными универсальным типом.

  • KeyValuePair<TKey, TValue> в данном случае открытый тип генератора.Он имеет некоторые параметры типа, но они уже определены в другом месте (в этом словаре в словаре).

  • Dictionary<string, int> будет закрытый тип общего типа.

Смежные вопросы