铸造和在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的对象。 这在某些情况下派上用场。