简体   繁体   English

获取通用接口的实现类型

[英]Get implemented types of generic interface

I have an generic interface and I would like to have a list of the implemented data types. 我有一个通用接口,我想提供一个已实现数据类型的列表。 With the following code I don't get any type returned. 使用以下代码,我不会得到任何类型的返回。 (t in types) (类型)

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);
}

This is an example of an implementation of the interface: 这是接口实现的示例:

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

Interface it selves: 自己的界面:

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

public interface IDataTypeConverter<TDataType>
{

}

What am I doing wrong here, why don't I get decimal as a type in my list? 我在这里做错了什么,为什么我的列表中没有十进制呢?

You're almost there. 你快到了。 You're checking to see if your classes are assignable to the open generic type IDataTypeConverter<> which they are not. 您正在检查您的类是否可分配给开放的通用类型 IDataTypeConverter<> ,而不是。 They are only assignable to a closed generic type like IDataTypeConverter<decimal> (or other data types for TDataType ) 它们只能分配给封闭的通用类型,例如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

I think there might be a simpler way to check, but this will do the job. 我认为可能有一种更简单的检查方法,但这可以完成工作。 It grabs all interfaces for a type, and for each one that's a generic interface, it checks if it's underlying open generic definition is IDataTypeConverter<> . 它获取一个类型的所有接口,并为每个属于通用接口的接口检查其基础开放通用定义是否为IDataTypeConverter<>

EDIT: Another way to demonstrate what I mean, your existing code would work if for type you assigned typeof(IDataTypeConverter<decimal>) instead. 编辑:另一种方式来说明我的意思, 如果您为type分配了typeof(IDataTypeConverter<decimal>) ,则您现有的代码将起作用。 That works because your types would be assignable to a IDataTypeConverter<decimal> but they're not assignable to IDataTypeConverter<> because such an operation has no meaning in C#. 之所以IDataTypeConverter<decimal>是因为您的类型可以分配给IDataTypeConverter<decimal>但不能分配给IDataTypeConverter<>因为这样的操作在C#中没有意义。

Your type variable contains generic type definition, IDataTypeConverter is not its descendant. 您的类型变量包含通用类型定义,IDataTypeConverter不是其后代。 So IDataTypeConverter is not assignable from IDataTypeConverter<>. 因此,不能从IDataTypeConverter <>分配IDataTypeConverter。

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

To check that some generic type is of the same generic type definition you can use predicate: 要检查某个通用类型是否具有相同的通用类型定义,可以使用谓词:

x => .GetInterfaces()
     .Any(item => item.IsGenericType && item.GetGenericTypeDefinition() == type)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM