Вы ищете GetGenericTypeDefinition
:
var t = typeof(Func<int, string>);
var tGeneric = t.GetGenericTypeDefinition();
Assert.AreEqual(typeof(Func<,>), tGeneric);
Если после этого вы хотите знать, если тип является один из многих вариантов Func<>
, то ваш лучший лучше просто сделать что-то как это. Проверка имен типов, как это было предложено в другом месте совершенно не так, как проверить идентичность типа:
static Type[] funcGenerics = new[]{
typeof(Func<>), typeof(Func<,>), typeof(Func<,,>), typeof(Func<,,,>),
/* and so on... */
}
//there are other ways to do the above - but this is the most explicit.
static bool IsFuncType(Type t)
{
if(t.IsGenericTypeDefinition)
return funcGenerics.Any(tt => tt == t);
else if(t.IsGenericType)
return IsFuncType(t.GetGenericTypeDefinition());
return false;
}
Ваша терминология неверна - что я подозреваю, почему вы получили downvote на ваш вопрос. Базовый тип - это тип, на который наследуется тип (а не интерфейс, который отличается, хотя концептуально очень похож).
Родовое определение типа лучше рассматривать как как шаблон (сильные квалификации там, поскольку термин «шаблон» используется в C++ и, в то время как визуально они похожи очень разные по реализации).
Более точно, Func<,>
это общее определение типа, тогда как Func<int, string>
является закрытым родовым (далее «общего типа»).
Вы также можете иметь открытый общий характер, который является, где аргументы типа являются общими параметрами - например, при:
class MyType<T> : List<T> { }
Тогда List<T>
является открытым родовым с определением List<>
универсального типа, поскольку T
является общий параметр, который не будет закрыт до MyType<T>
, ссылается на конкретный аргумент типа, например int
или string
.
Наконец, только потому, что куча общих типов имеет одно и то же общее имя, например. Func<>
, Func<,>
и Func<,,>
это не значит, что они каким-либо образом связаны. На уровне типа нет явного соединения, поэтому вам нужно проверить все эти типы, и почему нет общей «базы», как вы выразились. Однако, если все они имеют общий интерфейс или базовый класс, вы можете - путем проверки совместимости с этим интерфейсом или базовым типом.
Учитывая общее определение типа, вы можете создавать общие типы, используя MakeGenericType
, как уже упоминал Джеффри Чжан.
Что вы подразумеваете под базовым типом? Вы хотите получить 'Func <>'? –
@ user986697 - обновил мой ответ с фактическим решением того, что вы просите, и еще несколько объяснений, которые могут помочь вам в будущем. –