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

age*_*t47 38 c# casting c#-4.0

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

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);
}
Run Code Online (Sandbox Code Playgroud)

如你所见,我有3个选择,那么我应该使用哪个?其实之间有什么区别IsAssignableFrom,IsInstanceOfTypeis运营商?

Jac*_*cob 55

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

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

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

如果您没有实例,并且只想检查a Type和其他理论实例之间的兼容性Type,请使用IsAssignableFrom.

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

  • IsAssignableFrom 和 IsInstanceOfType 之间还有一个区别。在某些类型中,即使类型 B 不是类型 A 的实例,类型 A 也可以分配给类型 B。例如: class B { } class D : B { } interface IGeneric&lt;out T&gt; { } typeof(IGeneric&lt;B &gt;).IsAssignableFrom(typeof(IGeneric&lt;D&gt;); &lt;== 这个表达式是真的 typeof(IGeneric&lt;D&gt;).IsInstanceOfType(typeof(IGeneric&lt;B&gt;); &lt;== 这个表达式是假的 (3认同)

Mat*_*son 10

我猜你正在有效地实现一个as与值类型和引用类型一起使用的运算符版本.

我会去:

public static T SafeCastAs<T>(this object obj)
{
    return (obj is T) ? (T) obj : default(T);
}
Run Code Online (Sandbox Code Playgroud)

IsAssignableFrom适用于类型,并is与实例一起使用.他们会在你的情况下给你相同的结果,所以你应该使用最简单的版本恕我直言.

至于IsInstanceOfType:这是以实施方式实施的IsAssignableFrom,因此没有区别.

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

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