我想创建一个返回类型(或IEnumerable类型)的方法,该类型实现一个带有类型参数的特定接口 - 但是我想通过该泛型类型参数本身进行搜索。作为一个例子,这更容易证明:
我想要的方法签名:
public IEnumerable<Type> GetByInterfaceAndGeneric(Type interfaceWithParam, Type specificTypeParameter)
然后如果我有下面的对象
public interface IRepository<T> { };
public class FooRepo : IRepository<Foo> { };
public class DifferentFooRepo : IRepository<Foo> {};
然后我希望能够做到:
var repos = GetByInterfaceAndGeneric(typeof(IRepository<>), typeof(Foo));
并获取包含FooRepo
和DifferentFooRepo
类型的IEnumerable。
这与this question非常相似,但是使用该示例我想同时搜索IRepository<>
和User
。
答案 0 :(得分:1)
你可以这样试试;
public static IEnumerable<Type> GetByInterfaceAndGeneric(Type interfaceWithParam, Type specificTypeParameter)
{
var query =
from x in specificTypeParameter.Assembly.GetTypes()
where
x.GetInterfaces().Any(k => k.Name == interfaceWithParam.Name &&
k.Namespace == interfaceWithParam.Namespace &&
k.GenericTypeArguments.Contains(specificTypeParameter))
select x;
return query;
}
<强>用法强>
var types = GetByInterfaceAndGeneric(typeof(IRepository<>), typeof(Foo)).ToList();
答案 1 :(得分:1)
要重构@lucky的答案,我更喜欢将类型与通用类型定义进行比较,而不是使用类型名称:
static readonly Type GenericIEnumerableType = typeof(IEnumerable<>);
//Find all types that implement IEnumerable<T>
static IEnumerable<T> FindAllEnumerableTypes<T>(Assembly assembly) =>
assembly
.GetTypes()
.Where(type =>
type
.GetInterfaces()
.Any(interf =>
interf.IsGenericType
&& interf.GetGenericTypeDefinition() == GenericIEnumerableType
&& interf.GenericTypeArguments.Single() == typeof(T)));
或者,您可以检查是否可以从interf
分配GenericIEnumerableType.MakeGenericType(typeof(T))
或以其他方式分配