获取实现的通用接口类型

时间:2014-06-10 10:04:00

标签: c# linq generics reflection interface

我有一个通用接口,我想有一个已实现数据类型的列表。 使用以下代码,我不会返回任何类型。 (吨型)

var type = typeof (IDataTypeConverter<>);
var types = AppDomain.CurrentDomain.GetAssemblies()
                     .SelectMany(x => x.GetTypes())
                     .Where(x => type.IsAssignableFrom(x) && !x.IsInterface);

foreach (var t in types)
{
    var instance = (IDataTypeConverter)Activator.CreateInstance(t); 
    PropertiesConverter.Add(t, instance);
}

这是接口实现的一个示例:

public class DecimalConverter : IDataTypeConverter, IDataTypeConverter<decimal>
    {
     ...
    }

自行界面:

public interface IDataTypeConverter
{
    object Convert(object value);
}

public interface IDataTypeConverter<TDataType>
{

}

我在这里做错了什么,为什么我在列表中不能得到小数?

2 个答案:

答案 0 :(得分:2)

你快到了。您正在检查您的类是否可分配给开放通用类型 IDataTypeConverter<>,而不是。它们只能分配给已关闭的泛型类型,例如IDataTypeConverter<decimal>(或TDataType的其他数据类型)

var type = typeof (IDataTypeConverter<>);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(x => x.GetTypes())
    .Where(x => !x.IsInterface) //ignore interface definitions
    .Where(x => x.GetInterfaces() //for each interface implemented
        .Where(i => i.IsGenericType) //if they're a generic interface
        .Any(i => i.GetGenericTypeDefinition() == type)); //check its open-generic

我认为可能有一种更简单的方法可以检查,但这可以完成这项工作。它抓取一个类型的所有接口,并且对于每个接口,它检查它的底层开放泛型定义是否为IDataTypeConverter<>

编辑:另一种展示我的意思的方法是,现有的代码可以用 if 代替type typeof(IDataTypeConverter<decimal>)。这是有效的,因为您的类型可以分配给IDataTypeConverter<decimal>,但它们不能分配给IDataTypeConverter<>,因为这样的操作在C#中没有意义。

答案 1 :(得分:2)

您的类型变量包含泛型类型定义,IDataTypeConverter不是其后代。因此IDataTypeConverter不能从IDataTypeConverter&lt;&gt;。

分配
Console.WriteLine(typeof(IDataTypeConverter<>).IsGenericTypeDefinition);
Console.WriteLine(typeof(IDataTypeConverter<decimal>).IsGenericTypeDefinition);

要检查某些泛型类型是否具有相同的泛型类型定义,可以使用谓词:

x => .GetInterfaces()
     .Any(item => item.IsGenericType && item.GetGenericTypeDefinition() == type)
相关问题