IsAssignableFrom, IsInstanceOfType和is关键字有什么区别?

本文关键字:什么 区别 关键字 is IsInstanceOfType IsAssignableFrom | 更新日期: 2023-09-27 18:07:40

我有一个扩展方法来安全转换对象,看起来像这样:

public static T SafeCastAs<T>(this object obj) {
    if (obj == null)
        return default(T);
    // which one I should use?
    // 1. IsAssignableFrom
    if (typeof(T).IsAssignableFrom(obj.GetType()))
        return (T)obj;
    // 2. IsInstanceOfType
    if (typeof(T).IsInstanceOfType(obj))
        return (T) obj;
    // 3. is operator
    if (obj is T)
        return (T) obj;
    return default(T);
}

如你所见,我有3个选择,那么我应该用哪一个呢?实际上IsAssignableFrom, IsInstanceOfTypeis算子有什么区别?

IsAssignableFrom, IsInstanceOfType和is关键字有什么区别?

你可以用任何你知道的信息。

如果您想要检查一个实例和一个静态类型,请使用is

如果你没有静态类型,你只有一个Type对象,但你有一个实例,你想检查,使用IsInstanceOfType

如果你没有实例,你只是想检查Type和另一个Type的理论实例之间的兼容性,使用IsAssignableFrom

但实际上似乎只是重新实现了as操作符(除了您的操作符也适用于非空值类型,这通常不是一个大的限制)。

我猜你是在有效地实现as操作符的一个版本,它可以与值类型和引用类型一起工作。

我会选:

public static T SafeCastAs<T>(this object obj)
{
    return (obj is T) ? (T) obj : default(T);
}

IsAssignableFrom适用于类型,is适用于实例。在你的情况下,它们会给你相同的结果,所以我认为你应该使用最简单的版本。

对于IsInstanceOfType:这是按照IsAssignableFrom来实现的,所以不会有区别。

你可以通过使用Reflector来查看IsInstanceOfType()的定义来证明:

public virtual bool IsInstanceOfType(object o)
{
    if (o == null)
    {
        return false;
    }
    return this.IsAssignableFrom(o.GetType());
}

我想你应该用"as"代替你的自定义"SafeCastAs"。但这将只适用于类(不是结构),所以如果你想使用这种方法的结构以及我可以得到它。

操作符"is"基本上提供了与Type相同的功能。IsAssignableFrom,所以你可以只保留"is",它检查你是否可以安全地将obj转换为T,没有异常。所以它会在你的方法中覆盖之前的检查。但是您应该注意,由于用户定义的转换:显式和隐式关键字,它不会检查您是否可以将obj分配给T。

这些函数和操作符具有不同的含义。如果你有对象,你总能得到类型。所以你不是在做你已经做的事,而是在做你需要做的事。

当你在处理一个类的层次结构时,差异是非常明显的。

看下面的例子

      class ABase
        {
        }
        class BSubclass : ABase
        {
        }
    ABase aBaseObj = new ABase();
                BSubclass bSubclassObj = new BSubclass();
                ABase subObjInBaseRef = new BSubclass();

不同的操作产生不同的结果。

typeof(ABase).IsInstanceOfType(aBaseObj) = True
typeof(ABase).IsInstanceOfType(bSubclassObj) = True
typeof(ABase).IsInstanceOfType(bSubclassObj) = True
typeof(BSubclass).IsInstanceOfType(aBaseObj) = False
bSubclassObj is ABase = True
aBaseObj is BSubclass = False
subObjInBaseRef is BSubclass = True
subObjInBaseRef is BSubclass = True
typeof(ABase).IsAssignableFrom(typeof(BSubclass))  = True
typeof(BSubclass).IsAssignableFrom(typeof(ABase))= False

在没有层次结构的情况下,可能一切都是相同的。但是如果使用层次结构,IsAssignableFrom、is和IsInstanceOfType会产生不同的结果。

有更多可能的组合可以尝试。例如,您可以引入一个与本例中现有类没有任何关系的类C。