检查类型是否在不考虑泛型类型参数的情况下实现了泛型接口
本文关键字:情况下 实现 泛型接口 泛型类型参数 类型 是否 不考虑 检查 | 更新日期: 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
,你就可以简单地从字典中调用委托。