郎朗坤
我仔细研究了其中的一些样本,发现它们在某些情况下是缺乏的。此版本适用于各种泛型:类型、接口及其类型定义。public static bool InheritsOrImplements(this Type child, Type parent){
parent = ResolveGenericTypeDefinition(parent);
var currentChild = child.IsGenericType
? child.GetGenericTypeDefinition()
: child;
while (currentChild != typeof (object))
{
if (parent == currentChild || HasAnyInterfaces(parent, currentChild))
return true;
currentChild = currentChild.BaseType != null
&& currentChild.BaseType.IsGenericType
? currentChild.BaseType.GetGenericTypeDefinition()
: currentChild.BaseType;
if (currentChild == null)
return false;
}
return false;}private static bool HasAnyInterfaces(Type parent, Type child){
return child.GetInterfaces()
.Any(childInterface =>
{
var currentInterface = childInterface.IsGenericType
? childInterface.GetGenericTypeDefinition()
: childInterface;
return currentInterface == parent;
});}private static Type ResolveGenericTypeDefinition(Type parent){
var shouldUseGenericType = true;
if (parent.IsGenericType && parent.GetGenericTypeDefinition() != parent)
shouldUseGenericType = false;
if (parent.IsGenericType && shouldUseGenericType)
parent = parent.GetGenericTypeDefinition();
return parent;}以下是单元测试:protected interface IFooInterface{}protected interface IGenericFooInterface<T>{}protected class FooBase{}protected class FooImplementor
: FooBase, IFooInterface{}protected class GenericFooBase
: FooImplementor, IGenericFooInterface<object>{}protected class GenericFooImplementor<T>
: FooImplementor, IGenericFooInterface<T>{}[Test]public void Should_inherit_or_implement_non_generic_interface(){
Assert.That(typeof(FooImplementor)
.InheritsOrImplements(typeof(IFooInterface)), Is.True);}[Test]public void Should_inherit_or_implement_generic_interface(){
Assert.That(typeof(GenericFooBase)
.InheritsOrImplements(typeof(IGenericFooInterface<>)), Is.True);
}[Test]public void Should_inherit_or_implement_generic_interface_by_generic_subclass(){
Assert.That(typeof(GenericFooImplementor<>)
.InheritsOrImplements(typeof(IGenericFooInterface<>)), Is.True);
}[Test]public void Should_inherit_or_implement_generic_interface_by_generic_subclass_not_caring_about_generic_type_parameter(){
Assert.That(new GenericFooImplementor<string>().GetType()
.InheritsOrImplements(typeof(IGenericFooInterface<>)), Is.True);
}[Test]public void Should_not_inherit_or_implement_generic_interface_by_generic_subclass_not_caring_about_generic_type_parameter(){
Assert.That(new GenericFooImplementor<string>().GetType()
.InheritsOrImplements(typeof(IGenericFooInterface<int>)), Is.False);
}[Test]public void Should_inherit_or_implement_non_generic_class(){
Assert.That(typeof(FooImplementor)
.InheritsOrImplements(typeof(FooBase)), Is.True);}[Test]public void Should_inherit_or_implement_any_base_type(){
Assert.That(typeof(GenericFooImplementor<>)
.InheritsOrImplements(typeof(FooBase)), Is.True);}