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

时间:2013-04-06 16:19:55

标签: c# c#-4.0 casting

我有一个安全投射对象的扩展方法,如下所示:

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个选择,那么我应该使用哪一个?实际上IsAssignableFromIsInstanceOfTypeis运算符之间有什么区别?

4 个答案:

答案 0 :(得分:51)

您可以使用您拥有的任何信息。

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

如果您没有静态类型,那么您只有一个Type对象,但是您有一个要检查的实例,请使用IsInstanceOfType

如果您没有实例,并且只想检查Type的理论实例与另一个Type的理论实例之间的兼容性,请使用IsAssignableFrom

但实际上你似乎只是在重新实现as operator(除了你的也可以用于非可空值类型,这通常不是一个很大的限制)。

答案 1 :(得分:10)

我猜你有效地实现了一个适用于值类型和引用类型的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());
}

答案 2 :(得分:3)

我猜你应该选择“as”而不是自定义的“SafeCastAs”。但这只适用于类(不是结构),所以如果你想将这个方法用于结构,我也可以得到它。

运算符“is”基本上与Type.IsAssignableFrom相同,因此您只能保留“is”,它会检查您是否可以安全地将obj强制转换为T,没有异常。因此,它将涵盖您的方法中的先前检查。但是你应该知道它不会检查你是否可以将obj分配给T,因为用户定义了转换:explicitimplicit关键字。

答案 3 :(得分:0)

这些功能和操作符具有不同的含义。如果你有对象,你总是可以得到类型。所以你不会对你所拥有的东西开展工作,但你会做需要做的事情。

当您使用类层次结构时,差异非常明显。

请看以下示例

      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,是,IsInstanceOfType会产生不同的结果。

可以尝试更多可能的组合。例如,您可以在此示例中引入与现有类无关的C类。

相关问题