尽管 Slava 的解决方案有效,但总的来说,它并不是完全安全的,因为Contains
. It is某些其他接口/类型可能包含您正在搜索的接口的名称。在这种情况下,假设您有另一个名为IEntityModelBuilderHelper
.
此外,只需很少的努力,您就可以将此代码概括为更强大的功能。考虑以下两种方法:
public static IEnumerable<Type> GetAllTypes(Type genericType)
{
if (!genericType.IsGenericTypeDefinition)
throw new ArgumentException("Specified type must be a generic type definition.", nameof(genericType));
return Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.GetInterfaces()
.Any(i => i.IsGenericType &&
i.GetGenericTypeDefinition().Equals(genericType)));
}
And,
public static IEnumerable<Type> GetAllTypes(Type genericType, params Type[] genericParameterTypes)
{
if (!genericType.IsGenericTypeDefinition)
throw new ArgumentException("Specified type must be a generic type definition.", nameof(genericType));
return Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => t.GetInterfaces()
.Any(i => i.IsGenericType &&
i.GetGenericTypeDefinition().Equals(genericType) &&
i.GetGenericArguments().Count() == genericParameterTypes.Length &&
i.GetGenericArguments().Zip(genericParameterTypes,
(f, s) => s.IsAssignableFrom(f))
.All(z => z)));
}
前者将为您提供实现所提供的泛型类型的所有类型定义, 那是typeof(MyGenericType<>)
,对泛型类型参数没有任何限制。后者将执行相同的操作,但具有提供的类型约束。
考虑以下类型:
public interface IFoo<T> { }
public interface IEntity { }
public class A : IEntity { }
public class Foo : IFoo<IEntity> { }
public class FooA : IFoo<A> { }
public class FooS : IFoo<string> { }
var types = GetAllTypes(typeof(IFoo<>));
将返回 3 种类型:{ Foo, FooA, FooS }
while var types = GetAllTypes(typeof(IFoo<>), typeof(IEntity));
将仅返回两种类型:{ Foo, FooA }
.