35

我有一个界面

public interface MyInterface<TKey, TValue>
{
}

实现无关紧要。现在我想检查给定类型是否是该接口的实现。此方法失败

public class MyClass : MyInterface<int, string>
{
}

但我不知道如何进行检查。

public void CheckIfTypeImplementsInterface(Type type)
{
    var result1 = typeof(MyInterface<,>).IsAssignableFrom(type); --> false
    var result2 = typeof(MyInterface<int,string>).IsAssignableFrom(type); --> true
}

我必须做什么才能使 result1 为真?

4

2 回答 2

54

据我所知,这样做的唯一方法是获取所有接口并查看泛型定义是否与所需的接口类型匹配。

bool result1 = type.GetInterfaces()
    .Where(i => i.IsGenericType)
    .Select(i => i.GetGenericTypeDefinition())
    .Contains(typeof(MyInterface<,>));

编辑:正如乔恩在评论中指出的那样,你也可以这样做:

bool result1 = type.GetInterfaces()
    .Where(i => i.IsGenericType)
    .Any(i => i.GetGenericTypeDefinition() == typeof(MyInterface<,>));
于 2013-08-14T13:43:36.437 回答
3

通常,只有在接口包含一些不依赖于泛型类型参数的功能时才需要这种行为。如果您可以控制接口,最好的解决方案是让类型相关部分继承自非类型相关部分。例如,如果现有的集合接口不存在,可以将它们定义为:

interface ICountable 
  { CollectionAttribute Attributes {get;} int Count {get;} }
interface ICollection<T> : IEnumerable<T> ICountable
  { ... and other stuff ... }

如果用 完成了这样的事情ICollection,那么期望一个IEnumerable<Animal>但得到一个CatList仅实现的类型的对象的代码IList<Cat>使用该对象的成员将没有问题Count(请注意,List<Animal>实现非泛型ICollection,但其他IList<Animal>实现可能不会)。

事实上,如果你的任务是让代码以某种方式找到你期望 a的Count方法,那么构建类似 a 的东西可能是值得的,这样一旦你找到了实现,你就可以构造一个委托到一个方法,该方法会将其参数转换为,调用它并返回其结果。如果您有这样的字典,那么如果您有另一个字典,您将能够简单地从字典中调用委托。ICollection<Cat>IEnumerable<Animal>Dictionary<Type, Func<IEnumerable<Animal>, int>CatListICollection<Cat>.CountICollection<Cat>CountCatList

于 2013-08-14T16:06:30.570 回答