C#Casting性能影响

Dan*_*ell 20 c#

在C#中使用'as'关键字使转换失败时,返回null.背景中发生了什么?它只是简单地抑制异常,所以我不必为失败编写处理代码吗?

我对它的性能特征感兴趣,而不是用try-catch包裹的典型演员.

Gre*_*ech 50

它使用IL指令isinst执行转换而不是castclass转换时使用的指令.这是一个特殊的指令,如果有效则执行转换,否则null在堆栈上留下.所以不,它不只是抑制异常,并且比这样做快几个数量级.

请注意,isinst指令之间的行为存在一些差异castclass- 主要的是isinst不考虑用户定义的强制转换运算符,它只考虑直接继承层次结构,例如,如果定义以下两个没有继承层次结构的类但是显式转换运算符:

class A
{
    public int Foo;
}

class B
{
    public int Foo;

    public static explicit operator B(A a)
    {
        return new B { Foo = a.Foo };
    }
}
Run Code Online (Sandbox Code Playgroud)

然后以下将成功:

var a = new A { Foo = 3 };
var b = (B)a;
Console.WriteLine(b.Foo); // prints 3
Run Code Online (Sandbox Code Playgroud)

但是以下不能编译,错误'无法通过引用转换,装箱转换,拆箱转换,换行转换或空类型转换将类型'A'转换为'B'

var a = new A { Foo = 3 };
var b = a as B;
Run Code Online (Sandbox Code Playgroud)

因此,如果您确实设置了任何用户定义的强制转换(由于这个原因和其他原因,对引用类型通常是个坏主意),那么您应该意识到这种差异.


Cha*_*ana 8

并添加到格雷格的优秀帖子......

第一次在运行时引用一个新的Type时,CLR将一个名为COREINFO_CLASS_STRUCT(或类似的东西)的结构加载到内存中,该结构包含指向COREINFO_CLASS_STRUCT该对象派生自的基类的对象的指针...这有效COREINFO_CLASS_STRUCT为Type的继承链创建一个链接的对象列表,该列表终止于COREINFO_CLASS_STRUCTfor System.Object.当你执行时isinst,(或它是类似的方法castclass)它只需要找到COREINFO_CLASS_STRUCT你正在检查的对象的具体类型的内存结构,并遍历这个链表以查看你试图转换的Type是否在列表中.

它还包含一个指向单独数组的指针,该数组包含Type实现的所有接口,如果您尝试转换为接口,则必须单独搜索.