В чем разница между типичным типом и определением общего типа?

Я изучаю отражение .net, и мне сложно определить разницу.

Из того, что я понимаю, List<T> - это определение общего типа. Означает ли это, что для .net-отражения T является общим типом?

В частности, я предполагаю, что я ищу больше фона для функций Type.IsGenericType и Type.IsGenericTypeDefinition.

Спасибо!

Ответ 1

В вашем примере List<T> - это определение общего типа. T называется типичным параметром типа. Когда параметр типа указан как в List<string> или List<int> или List<double>, тогда у вас есть общий тип. Вы можете видеть, что, запустив некоторый код, подобный этому...

public static void Main()
{
    var l = new List<string>();
    PrintTypeInformation(l.GetType());
    PrintTypeInformation(l.GetType().GetGenericTypeDefinition());
}

public static void PrintTypeInformation(Type t)
{
    Console.WriteLine(t);
    Console.WriteLine(t.IsGenericType);
    Console.WriteLine(t.IsGenericTypeDefinition);    
}

Будет напечатан

System.Collections.Generic.List`1[System.String] //The Generic Type.
True //This is a generic type.
False //But it isn't a generic type definition because the type parameter is specified
System.Collections.Generic.List`1[T] //The Generic Type definition.
True //This is a generic type too.                               
True //And it also a generic type definition.

Другой способ получить определение общего типа напрямую - typeof(List<>) или typeof(Dictionary<,>).

Ответ 2

Это поможет объяснить это:

List<string> lstString = new List<string>();
List<int> lstInt = new List<int>();

if (lstString.GetType().GetGenericTypeDefinition() ==
    lstInt.GetType().GetGenericTypeDefinition())
{
    Console.WriteLine("Same type definition.");
}

if (lstString.GetType() == lstInt.GetType())
{
    Console.WriteLine("Same type.");
}

Если вы запустите его, вы получите первый тест, потому что оба элемента реализуют тип List<T>. Второй тест завершился неудачно, потому что List<string> не совпадает с List<int>. Определение общего типа сравнивает исходный родовое значение до T.

Тип IsGenericType просто проверяет, определен ли общий T. IsGenericTypeDefinition проверяет, не определено ли общее T. Это полезно, если вы хотите знать, были ли определены два объекта из одного базового типа, такого как первый пример List<T>.