2014-12-11 3 views
1

Как узнать базовый тип универсального типа?C# - Знание базового типа общего типа

Например

Func<A, B> 

Я хотел бы быть в состоянии сказать, что это Func <> .. но, по-видимому, Func <,> отличается от Func <> - Есть ли способ как-то поймать их обоих, или Func < ,,,> и т. д.?

+0

Что вы подразумеваете под базовым типом? Вы хотите получить 'Func <>'? –

+0

@ user986697 - обновил мой ответ с фактическим решением того, что вы просите, и еще несколько объяснений, которые могут помочь вам в будущем. –

ответ

1

Нет, вы не можете, нет базового типа типа Гернера. Если вы хотите получить определенный тип типа по типам параметров, вы можете использовать MakeGenericType. Например:

//get Func<int, string> type 
typeof(Func<>).MakeGenericType(typeof(int), typeof(string)); 

Если вы хотите, чтобы получить Generic Тип от указанного общего типа, Вы можете использовать GetGenericTypeDefinition. Например:

//get Func<,> type 
typeof(Func<int, string>).GetGenericTypeDefinition(); 
+0

Не лучше GetGenericDefinition? 'typeof (Func ) .GetGenericTypeDefinition(). Equals (typeof (Func <>))'; –

+0

@pwas Это классно, я не знаю этого метода раньше. Могу ли я обновить базу ответов, которую вы прокомментируете? –

+0

да, без проблем –

3

Вы ищете 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, как уже упоминал Джеффри Чжан.

0

Это потому, что Func< A, B > не наследует от Func<> Это общее на основе Func<,>.

Однако, вы заметите, что

typeof(Func<int, int>).FullName // equals "System.Func`2... 
typeof(Func<int, int, int>).FullName // equals "System.Func`3... 

Это немного некрасиво, но вы можете использовать что-то вроде

YourType.FullName.StartsWith("System.Func") 

Надеетесь, что это помогает

Edit: Почему бы не использовать YourType.GetGenericTypeDefinition() ?

Потому что typeof(Func<int, int>).GetGenericTypeDefinition() возвращает Func<,>

и typeof(Func<int, int, int>).GetGenericTypeDefinition() возвращение Func<,,>.

Func<,> и Func<,,> не идентичны.

+0

Не думаю, что это хорошая идея полагаться на FullName. Лучше использовать 'GetGenerictTypeDefinition'. –

+0

извините - это просто не правильный способ сделать то, что ОП задает, хотя и использует неясный язык –

+0

@pwas, но 'GetGenericTypeDefinition' не решает проблему. Проблема заключается в том, как узнать, является ли это Func произвольной arity. GetGenericTypeDefinition просто возвращает открытый общий тип той же арности. –

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