铸造和在C#中使用“as”有什么区别?
如果有差异,做下面两个演员的两种方式有什么区别?
在这种情况下, e
是一个GridViewRowEventArgs
对象。
GridView gv = (GridView)e.Row.FindControl("gv"); //first way GridView gv2 = e.Row.FindControl("gv") as GridView; //second way
差异是:
- 如果
InvalidCastException
失败,则会引发InvalidCastException
。 - 如果
as
运算符失败,它只是返回一个空引用。 - 你不能使用不可为空的值types(例如,你不能做“
o as int
”)。 - 演员操作员也用于拆箱。 (
as
可以用来取消空值types) - 演员操作员也可以执行用户定义的转换。
编辑:我写了其他地方什么时候我觉得适合使用哪个操作符。 这可能值得一读…
上面答案中没有提到的是意图 – 你为什么要进行转换,并且(更重要的是)在转换之后发生了什么?
例如,我已经看过类似下面的代码多次:
if ((foo as SomeType).SomeMethod()) { /* ... */ }
这可以与演员使用的版本进行比较:
if (((SomeType) foo).SomeMethod()) { /* ... */ }
那么,哪个更好?
演员是。
如果转换失败,使用as
会导致NullReferenceException
。
如果转换失败,使用InvalidCastException
将导致InvalidCastException
。
现在告诉我,这是一个更有用的例外debugging? 一个NullReferenceException
,几乎可以产生任何东西,或一个InvalidCastException
,让你知道究竟是哪里出了问题?
因此, 只能使用转换实际上是可选的(意味着在使用variables之前必须进行null
检查)。 否则,使用一个强制转换,从而使你的意图更加明确。
一般来说,静态转换和“as”之间的区别在于,如果转换失败,转换将抛出一个exception,而“as”只会将该variables设置为null。
“as”语句基本上会尝试转换variables,如果失败而不是抛出exception,则返回null。 因此,您正在投射的值必须是可以为空的 – 一个引用types或一个可为空的原语。 在你的例子中,你必须这样做:
int? i2 = o as int;
否则不会编译。
安全的演员为
variable as type
和…一样
(variable is type) ? (type)variable : (type)null
并不会为值types工作。
如果你使用了一个引用types,比如Table,那么第一个引发InvalidCastException,如果o不能分配给Table,第二个会返回null。
除了Jon指出的问题之外, as
关键字有效地将o
转换为SomeClass
。 如果o
不是从SomeClass
派生的,则返回null
。 而简单的演员将会抛出一个exception。
SomeClass i2 = o as SomeClass;
变
SomeClass i2; if (o is SomeClass) i2 = (SomeClass)o; else i2 = null;
我可能会在这里说明一个明显的问题,但是你用'as'expression的一件事情是,你保证会得到一个你要求的types的对象。 这在某些情况下派上用场。