有没有办法确定generics类型是否是从特定的generics类型定义构建的?

我有一个通用的方法:

Func<IEnumerable, bool> CreateFunction() 

其中T可以是任意数量的不同类型。 这个方法使用reflection做一堆东西,如果T是一个IDictionary ,不管字典的TKeyTValue我需要执行字典特定的代码。

所以可以调用该方法:

 var f = CreateFunction(); var f0 = CreateFunction(); var f1 = CreateFunction<IDictionary>(); var f2 = CreateFunction<Dictionary>(); var f3 = CreateFunction<SomeDerivedDictionaryType>(); 

等等

根据@Andy的回答澄清

最后我想知道Tinheritance自/实现IDictionary即使T本身是Dictionary或从该接口派生的其他类型。

 if(typeof(T) == typeof(IDictionary) 

不起作用,因为T是generics类型而不是generics类型定义。

并且在不知道TKeyTValue (在编译时不知道)的情况下,我无法对运行时我知道的任何具体类型进行比较。

我唯一想到的就是查看类型的名称或者用reflection检查它的方法,寻找能让我相信它是字典的方法(即查找ContainsKeyget_Item )。

有没有直接的方法来做出这种决定?

你可以做点什么

 class Program { static void Main(string[] args) { Example>.IsDictionary(); Example>.IsDictionary(); Example>.IsDictionary(); Console.ReadKey(); } } public class Example { public static void IsDictionary() { if (typeof(T).GetInterface(typeof(IDictionary<,>).Name) != null || typeof(T).Name.Contains("IDictionary")) { Console.WriteLine("Is IDictionary"); } else { Console.WriteLine("Not IDictionary"); } } } 

您可以避免使用IsGenericType和GetGenericTypeDefinition成员使用丑陋且具有潜在风险的类型名称字符串检查,如下所示:

 var type = typeof (T); if (typeof (IDictionary).IsAssignableFrom(type)) { //non-generic dictionary } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof (IDictionary<,>)) { //generic dictionary interface } else if (type.GetInterfaces().Any( i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof (IDictionary<,>))) { //implements generic dictionary } 

简单的方法就是这样:

 Type iDict = null; if (typeof(T).GetGenericTypeDefinition() == typeof(IDictionary<,>)) iDict = typeof(T); else iDict = typeof(T).GetInterface(typeof(IDictionary<,>).Name); if (iDict != null) { var genericParams = iDict.GetGenericArguments(); Type tKey = genericParams[0], tValue = genericParams[1]; } 

请注意,如果T实现了多个 IDictionary<,>接口,这将无法工作(抛出exception),但这可能适用于您的目的。

为了完整起见,这里有一个实现, 它将使用第一个具有多个IDictionary<,>接口的类型:

 Type iDict = t.GetType().GetInterfaces() .Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IDictionary<,>)) .FirstOrDefault(); if (iDict != null) { var genericParams = iDict.GetGenericArguments(); Type tKey = genericParams[0], tValue = genericParams[1]; } 

注意,在该第二例程中, t是对象,而T是第一例程中的类型。

我认为如果你调用Type.GetGenericTypeDefinition() ,它应该返回用于构造具体Type的“base”generics类型。

请注意,仅将此与IDictionary<,>比较可能还不够,因为如果有人传入Dictionary<,>的实例Dictionary<,>我认为您也希望使用它。 您可以检查Type是否实现了IDictionary<,>或者您可能能够调用Type.IsAssignableFrom() ,尽管基于doc我不确定它对generics类型的效果如何。