Что именно является «открытым универсальным типом» в .NET? [Дубликат

StackOverflow https://stackoverflow.com/questions/2173107

Вопрос

Этот вопрос уже имеет ответ здесь:

Я шел через Урок ASP.NET MVC и узнал, что для метода для квалификации в качестве действия для контроллера,

  • Не должно иметь «Открытый универсальный тип»

Я несколько разбираюсь и использую их в некоторой степени, но:

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

Решение

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

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

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

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

Следовательно 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> а. граница Открытый тип.

Во время выполнения вы можете использовать отражение для аргументов типа связывания, чтобы не указанные типы параметров несвязанных общих типов с 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<int,> или Dictionary<,string>.

Другие советы

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

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

Пример:

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

«Открытый универсальный тип» - это просто универсальный тип, который еще не имеет указанного типа (например, 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Тип открыт: ничего еще не назначено T. Отказ Когда вы делаете бетонный пикникблакет с определенным типом - например, написав PicnicBlanket<Food> p = new PicnicBlanket<Food>() - Теперь мы называем это закрыто.

Есть три вида общих типов. Чтобы сделать его коротким, в этой (упрощенном) декларации:

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

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

  • Dictionary<string, int> будет А. Закрытый построен родовой тип.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top