检查类型是否在不考虑泛型类型参数的情况下实现了泛型接口

本文关键字:情况下 实现 泛型接口 泛型类型参数 类型 是否 不考虑 检查 | 更新日期: 2023-09-27 18:27: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
}

我该怎么做才能使结果1为真?

检查类型是否在不考虑泛型类型参数的情况下实现了泛型接口

据我所知,实现这一点的唯一方法是获取所有接口,并查看通用定义是否与所需的接口类型匹配。

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

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

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

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

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>实现可能不会)。

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