[英]Check if a type implements a generic interface without considering the generic type arguments
I have an interface 我有一个界面
public interface MyInterface<TKey, TValue>
{
}
Implementations are irrelevant. 实现是无关紧要的。 Now I want to check if a given type is an implementation of that interface. 现在我想检查给定类型是否是该接口的实现。 This method fails for 这种方法失败了
public class MyClass : MyInterface<int, string>
{
}
But I don't know how to do the check. 但我不知道怎么做检查。
public void CheckIfTypeImplementsInterface(Type type)
{
var result1 = typeof(MyInterface<,>).IsAssignableFrom(type); --> false
var result2 = typeof(MyInterface<int,string>).IsAssignableFrom(type); --> true
}
What do I have to do for result1 to be true? 为了使result1真实,我该怎么做?
As far as I know, the only way to do this is to get all interfaces and see if the generic definition matches the required interface type. 据我所知,唯一的方法是获取所有接口,看看通用定义是否与所需的接口类型匹配。
bool result1 = type.GetInterfaces()
.Where(i => i.IsGenericType)
.Select(i => i.GetGenericTypeDefinition())
.Contains(typeof(MyInterface<,>));
EDIT: As Jon points out in the comments, you could also do: 编辑:正如乔恩在评论中指出的那样,你也可以这样做:
bool result1 = type.GetInterfaces()
.Where(i => i.IsGenericType)
.Any(i => i.GetGenericTypeDefinition() == typeof(MyInterface<,>));
Generally, such behavior is only required in cases where an interface contains some functionality which does not depend upon the generic type parameters. 通常,仅在接口包含一些不依赖于泛型类型参数的功能的情况下才需要这种行为。 If you have control over the interfaces, the best solution is to have the type-dependent parts inherit from a non-type dependent part. 如果您可以控制接口,那么最佳解决方案是使类型相关的部分继承自非类型相关部分。 For example, if the existing collection interfaces didn't exist, one might define them something like: 例如,如果现有的集合接口不存在,可以将它们定义为:
interface ICountable
{ CollectionAttribute Attributes {get;} int Count {get;} }
interface ICollection<T> : IEnumerable<T> ICountable
{ ... and other stuff ... }
Had such a thing been done with ICollection
, then code which was expecting an IEnumerable<Animal>
but got an object of type CatList
that just implements IList<Cat>
would have no problem using the Count
member of that object (note that List<Animal>
implements the non-generic ICollection
, but other IList<Animal>
implementations may not). 如果使用ICollection
完成了这样的事情,那么期待IEnumerable<Animal>
但得到CatList
类型的对象的CatList
只是实现了IList<Cat>
将使用该对象的Count
成员没有问题(请注意List<Animal>
实现非泛型ICollection
,但其他IList<Animal>
实现可能不会)。
As it is, if you're stuck with the task of having code somehow find the Count
method of ICollection<Cat>
when you're expecting an IEnumerable<Animal>
, it may be worthwhile to build something like a Dictionary<Type, Func<IEnumerable<Animal>, int>
so that once you've found that CatList
implements ICollection<Cat>.Count
you can construct a delegate to a method which will cast its argument to ICollection<Cat>
, call Count
on it, and return its result. 事实上,如果您在使用代码时以某种方式找到了ICollection<Cat>
的Count
方法,当您期望IEnumerable<Animal>
,可能需要构建像Dictionary<Type, Func<IEnumerable<Animal>, int>
这样的东西。 Dictionary<Type, Func<IEnumerable<Animal>, int>
这样一旦你发现CatList
实现了ICollection<Cat>.Count
你就可以构造一个方法的委托,该方法将其参数转换为ICollection<Cat>
,在其上调用Count
,并返回结果。 If you have such a dictionary, then if you're given another CatList
you'll be able to simply invoke the delegate from the dictionary. 如果您有这样的字典,那么如果您有另一个CatList
您将能够简单地从字典中调用该委托。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.