检查对象是否为T的子类的扩展方法

Mar*_*aro 6 .net c# .net-4.5

我正在尝试编写一个扩展方法来检查对象是否是T的子类.

这是我做的,但不被视觉工作室接受.

public static bool IsChildOf<T>(this object obj)
{
    return (typeof(obj).IsSubclassOf(typeof(T)));
}

[Test()]
public void IsChildOfTest()
{
    var dog = new Dog();
    var isAnimal = dog.IsChildOf<Animal>();
    Assert.That(isAnimal);
}
Run Code Online (Sandbox Code Playgroud)

知道我怎么写这个?

McG*_*gle 6

使用GetType而不是typeof当您有类型的实例时:

public static bool IsChildOf<T>(this object obj)
{
    return (obj.GetType().IsSubclassOf(typeof(T)));
}
Run Code Online (Sandbox Code Playgroud)


wes*_*ton 6

你可以使用is.但请注意,is并不完全相同IsSubclassOf.有关详细信息,请参阅Jeppe的优秀评论,我也在下面举例说明.

在旁注中,我不认为Java instanceof出于某种原因允许在这种通用情况下等效,但在C#中它是可以的.即:

public static bool IsChildOf<T>(this object obj)
{
    return obj is T;
}
Run Code Online (Sandbox Code Playgroud)

然后这使得它变得如此微不足道,以至于读者使用扩展方法比is直接使用更加困惑.如果您直接使用它,那么您的测试将如下所示:

[Test()]
public void IsChildOfTest()
{
    var dog = new Dog();
    var isAnimal = dog is Animal;
    Assert.That(isAnimal);
}
Run Code Online (Sandbox Code Playgroud)

is和之间的一个区别的例子IsSubclassOf:

[Test]
public void IsChildOfTest()
{
    var dog = new Dog();
    Assert.False(dog.GetType().IsSubclassOf(typeof(Dog)));
    Assert.True(dog is Dog);
}
Run Code Online (Sandbox Code Playgroud)

  • 赞成提到`是`.它并不完全等同于`Type.IsSubclassOf`.一些差异:如果`T`是与'obj`的运行时类型相同的*类,`is`表示`true`而`IsSubclassOf`表示`false`.如果`T`是一个接口,`is`检查`obj`是否代表`interface`,而`IsSubclassOf`只是说`false`.如果`obj`的运行时类型是(盒装)值类型,`is`按预期检查,而'IsSubclassOf`只是说不.`is`还认为共和逆变在仿制药,例如东西是`的IEnumerable <字符串>`也`的IEnumerable <对象>`(参见`IEnumerable的<出T>`). (3认同)

Dan*_*ner 5

public static Boolean IsChildOf<T>(this Object obj)
{
   // Don't forget to handle obj == null.
   return obj.GetType().IsSubclassOf(typeof(T));
}
Run Code Online (Sandbox Code Playgroud)