C# 如何将与特定C接口匹配的所有类型放在IDictionary中?

C# 如何将与特定C接口匹配的所有类型放在IDictionary中?,c#,generics,reflection,interface,C#,Generics,Reflection,Interface,我有许多类都在同一个接口中,都在同一个程序集中,都符合同一个通用接口: public class AppleFactory : IFactory<Apple> { ... } public class BananaFactory : IFactory<Banana> { ... } // ... 最好的方法是什么?我很难理解如何使用System.Reflection接口来实现这一点。问题将出现在匹配所有IFactory时,因为您必须指定T。最简单的解决方案是创建另一个接

我有许多类都在同一个接口中,都在同一个程序集中,都符合同一个通用接口:

public class AppleFactory : IFactory<Apple> { ... }
public class BananaFactory : IFactory<Banana> { ... }
// ...

最好的方法是什么?我很难理解如何使用System.Reflection接口来实现这一点。

问题将出现在匹配所有IFactory时,因为您必须指定T。最简单的解决方案是创建另一个接口IFactory,并使IFactory成为它的通用版本。然后可以匹配所有IFactory,然后构建字典

Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => t is IFactory)
    .ToDictionary(k => k.GetGenericArguments()[0],v => v);

匹配所有IFactory时会出现问题,因为您必须指定T。最简单的解决方案是创建另一个接口IFactory,并使IFactory成为它的通用版本。然后可以匹配所有IFactory,然后构建字典

Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => t is IFactory)
    .ToDictionary(k => k.GetGenericArguments()[0],v => v);

为了识别属于接口通用定义的类,我使用以下扩展方法:

public static class TypeExtensions
{
    public static bool IsGenericTypeOf(this Type t, Type genericDefinition)
    {
        return t.IsGenericType && genericDefinition.IsGenericType && t.GetGenericTypeDefinition() == genericDefinition.GetGenericTypeDefinition();
    }
}
然后可以使用Type.GetGenericArguments方法find T

这样你就会得到这样的结果:

var allTypes = ...; // Maybe: Assembly.GetExecutingAssembly().GetTypes()
var dictionary = allTypes.Where(t => t.IsGenericTypeOf(typeof(IFactory<>))).ToDictionary(t => t.GetGenericArguments()[0], t => t);

为了识别属于接口通用定义的类,我使用以下扩展方法:

public static class TypeExtensions
{
    public static bool IsGenericTypeOf(this Type t, Type genericDefinition)
    {
        return t.IsGenericType && genericDefinition.IsGenericType && t.GetGenericTypeDefinition() == genericDefinition.GetGenericTypeDefinition();
    }
}
然后可以使用Type.GetGenericArguments方法find T

这样你就会得到这样的结果:

var allTypes = ...; // Maybe: Assembly.GetExecutingAssembly().GetTypes()
var dictionary = allTypes.Where(t => t.IsGenericTypeOf(typeof(IFactory<>))).ToDictionary(t => t.GetGenericArguments()[0], t => t);
嗯-但我怎么能做到输入blankFactory=typeofIFactory?显然,编译器可以很好地处理丢失的类型参数-似乎这在反射中应该是可行的,这是困扰我的部分。嗯-但是我怎么能做到类型blankFactory=typeofifacture呢?显然,编译器可以很好地处理丢失的类型参数——似乎这在反射中是可行的,这正是困扰我的部分。