Что такое точно “открытый универсальный тип” в.NET? [дубликат]

114
задан abatishchev 17 November 2012 в 18:55
поделиться

4 ответа

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

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

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

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

Следовательно, T , List и Dictionary и Dictionary все открытые типы ( T и U - аргументы типа), тогда как List и Dictionary закрыты типы.

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

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

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 . Во время выполнения ясно, что аргументом типа является System.Int32 . Это делает List связанным открытым типом.

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

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

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

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

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

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

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

188
ответ дан 24 November 2019 в 02:34
поделиться

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

словарь <Строка, т> (или более точно словарь ) все еще открытый тип.

Пример:

void Foo<T>(Dictionary<string,T> dic) { ... }
9
ответ дан 24 November 2019 в 02:34
поделиться

Есть три вида родовых типов. Короче говоря, в этом (упрощенном) объявлении:

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

  • KeyValuePair в данном случае является открытым типовым типом . Он имеет некоторые параметры типа, но они уже определены в другом месте (в словаре, в данном случае).

  • Словарь<строка, int> будет закрытым построенным типовым типом.

6
ответ дан 24 November 2019 в 02:34
поделиться

«Открытый универсальный тип» - это просто универсальный тип, для которого еще не указан его тип (например, CargoCrate ). Он становится «закрытым» после присвоения конкретного типа (например, CargoCrate ).

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

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 открыт: для T еще ничего не назначено. Когда вы создаете конкретное одеяло для пикника определенного типа - например, написав PicnicBlanket p = new PicnicBlanket () , мы теперь называем его закрытым .

7
ответ дан 24 November 2019 в 02:34
поделиться
Другие вопросы по тегам:

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