强制转换:(NewType)vs. Object as NewType
Possible Duplicate: Casting vs using the 'as' keyword in the CLR
这两个演员之间的实际区别是什么?
SomeClass sc = (SomeClass)SomeObject; SomeClass sc2 = SomeObject as SomeClass;
通常,它们都应该被显式转换为指定的类型吗?
解决方案
回答
如果源类型不能转换为目标类型,则前者将引发异常。后者将导致sc2为空引用,但也不例外。
[编辑]
我最初的回答当然是最明显的区别,但是正如埃里克·利珀特(Eric Lippert)指出的那样,这不是唯一的区别。其他差异包括:
- 我们不能使用'as'运算符强制转换为不接受'null'作为值的类型
- 我们不能使用'as'来转换事物,例如将数字转换为不同的表示形式(例如,将float转换为int)。
最后,使用" as"与强制转换运算符,我们还说"我不确定是否会成功"。
回答
如果强制转换尝试失败,则括号强制转换将引发异常。如果转换尝试失败,则" as"转换将返回null。
回答
他们会抛出不同的异常。
():NullReferenceException
如:InvalidCastException
这可能有助于调试。
关键字" as"尝试强制转换对象,如果强制转换失败,将以静默方式返回null。如果强制转换失败,则()强制转换运算符将立即引发异常。
在非特殊情况下,如果期望转换失败,请使用"仅使用C" as"关键字。如果要依靠转换成功并且不准备接收任何可能失败的对象,则应使用()强制转换运算符,以便抛出适当且有用的异常。"
回答
有关代码示例和进一步的解释,请访问:http://blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html
还要注意,我们只能将as关键字与引用类型或者可为空的类型一起使用
double d = 5.34; int i = d as int;
IE:
double d = 5.34; int i = (int)d;
不会编译
回答
将编译。
DateTime i = (DateTime)value; // is like doing DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);
这是记住他们每个人遵循的过程的一种好方法,当我尝试确定哪种方法更适合我的情况时。
DateTime i = value as DateTime;
下一个应该很容易猜出它的作用
在第一种情况下,如果不能强制转换该值,则在第二种情况下,如果不能强制转换该值,则抛出异常,i设置为null。
回答
因此,在第一种情况下,如果强制转换失败,则在第二种强制转换中进行硬停止,然后进行软停止,稍后我们可能会遇到NullReferenceException。
回答
就像Parse和TryParse之间的区别一样。当我们期望TryParse可能会失败时,可以使用它,但是当我们确信它不会失败时,请使用Parse。
回答
要扩展Rytmis的注释,不能将as关键字用于结构(值类型),因为它们没有空值。
当强制转换失败时,使用" as"进行类型转换当然要快得多,因为它避免了引发异常的开销。
但是当转换成功时并不会更快。 http://www.codeproject.com/KB/cs/csharpcasts.aspx上的图形具有误导性,因为它没有解释其测量内容。
- 如果我们期望强制转换成功(即失败将是例外),请使用强制转换。
- 如果我们不知道它是否会成功,请使用" as"运算符并测试结果是否为null。
回答
底线是:
回答
对于那些具有VB.NET经验的人,(类型)与DirectCast相同,"按类型"与TryCast相同。
//if I know that SomeObject is an instance of SomeClass SomeClass sc = (SomeClass) someObject; //if SomeObject *might* be SomeClass SomeClass sc2 = someObject as SomeClass;
所有这些都适用于引用类型,值类型不能使用as
关键字,因为它们不能为null。
强制转换语法更快,但是只有成功时,失败的速度要慢得多。
//we need to know what someObject is SomeClass sc; SomeOtherClass soc; //use as to find the right type if( ( sc = someObject as SomeClass ) != null ) { //do something with sc } else if ( ( soc = someObject as SomeOtherClass ) != null ) { //do something with soc }
最佳做法是在不知道类型时使用as
:
但是,如果我们绝对确定someObject
是SomeClass
的实例,请使用强制转换。
回答
在.Net 2或者更高版本中,泛型意味着我们很少需要引用类型的无类型实例,因此后者的使用率较低。
回答
两种方法之间的区别在于,第一种((SomeClass)obj)可能导致类型转换器被调用。
回答
为了完整起见,埃里克·利珀特(Eric Lippert)在博客上发表了关于区别和一些警告的文章。
好吧," as"运算符"帮助"我们将问题掩埋得更低一些,因为当提供不兼容的实例时,它将返回null,也许我们将其传递给一个方法,该方法将其传递给另一个方法,依此类推,最后我们得到了"会得到一个NullReferenceException,这将使调试更加困难。
段落数量不匹配