铸造:(NewType)与对象作为NewType
可能重复:
在CLR中使用“as”关键字进行投射
这两个演员之间的区别究竟是什么?
SomeClass sc = (SomeClass)SomeObject; SomeClass sc2 = SomeObject as SomeClass;
通常情况下,他们都应该是明确的转换到指定的types?
如果源types不能转换为目标types,前者将抛出exception。 后者将导致sc2为空引用,但也不例外。
[编辑]
我原来的答案肯定是最明显的差异,但正如Eric Lippert所指出的那样 ,并不是唯一的答案。 其他差异包括:
- 您不能使用“as”运算符来转换为不接受“null”作为值的types
- 您不能使用“as” 将数字转换为不同的表示forms(例如float到int)。
最后,使用'as'与演员,你也说'我不知道这是否会成功。
另请注意,您只能将as关键字与引用types或可为空的types一起使用
即:
double d = 5.34; int i = d as int;
不会编译
double d = 5.34; int i = (int)d;
将编译。
使用“as”进行types转换当然要快得多,因为它避免了抛出exception的代价。
但是演员成功的时候不会更快。 http://www.codeproject.com/KB/cs/csharpcasts.aspx中的graphics是误导性的,因为它没有解释它正在测量什么。;
底线是:
-
如果你期望演员成功(即失败将是例外),使用演员。
-
如果您不知道是否成功,请使用“as”运算符并testing结果为null。
这两种方法的区别在于第一个((SomeClass)obj)可能会导致types转换器被调用。
这是一个很好的方法来记住每个人在试图决定哪一个更适合我的情况下使用的过程。
DateTime i = (DateTime)value; // is like doing DateTime i = value is DateTime ? value as DateTime : throw new Exception(...);
而下一个应该很容易猜到它的作用
DateTime i = value as DateTime;
在第一种情况下,如果无法强制转换值,那么如果无法强制转换,则在第二种情况下抛出exception,i将设置为空。
所以在第一种情况下,如果在第二次强制转换失败时进行了软停止,您可能会遇到NullReferenceExceptionexception。
那么“as”操作符“帮助”你把你的问题埋在低处,因为当它提供了一个不兼容的实例时,它将返回null,也许你会把它传递给一个方法,它会传递给另一个方法等等,会得到一个NullReferenceException,这将使你的debugging更加困难。
不要滥用它。 在99%的情况下,直接操作员的情况更好。
要扩展Rytmis的评论 ,你不能使用as关键字的结构(值types),因为他们没有空值。
所有这些都适用于引用types,值types不能使用as
关键字,因为它们不能为null。
//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
当你不知道的types:
//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 }
但是如果你确定someObject
是SomeClass
一个实例,那么就使用cast。
在.Net 2或以上的generics意味着你很less需要有一个参考类的非types的实例,所以后者不太经常使用。
如果转换尝试失败,则括号转换会引发exception。 如果强制转换尝试失败,则“as”强制转换返回null。
他们会抛出不同的例外。
():NullReferenceException
如:InvalidCastException
这可能有助于debugging。
“as”关键字尝试转换对象,如果转换失败,则以无提示方式返回null。 如果转换失败,()转换运算符将立即抛出exception。
“只有在非例外的情况下,如果您希望转换成功并且没有准备好接收任何可能失败的对象,那么您只能使用C#作为”关键字“转换操作符,以便引发适当和有用的exception。“
对于代码示例和进一步的解释: http : //blog.nerdbank.net/2008/06/when-not-to-use-c-keyword.html
这就像Parse和TryParse的区别。 如果您希望可能会失败,则使用TryParse,但是如果您有足够的保证,则不会因使用Parse而失败。
对于那些VB.NET经验的人来说,(type)和DirectCast是一样的,“as type”和TryCast是一样的。
为了完整起见, Eric Lippert有一篇关于这个差异的博客文章 ,以及一些注意事项。