在开发博客、在线代码示例和(最近)甚至是一本书中,我经常遇到这样的代码:

var y = x as T;
y.SomeMethod();

或者,更糟糕的是:

(x as T).SomeMethod();

这对我来说没有意义。如果你确定x是类型T,你应该使用直接强制转换:(T)x。如果不确定,可以使用as,但在执行某些操作之前需要检查是否为空。上面的代码所做的就是将一个(有用的)InvalidCastException转换为一个(没用的)NullReferenceException。

难道只有我一个人认为这是对as关键字的公然滥用吗?还是我错过了一些明显的东西,而上面的模式实际上是有意义的?


当前回答

我认为as关键字可以看作是样式更优雅的版本 dynamic_cast来自c++。

其他回答

只是因为人们喜欢它的样子,所以它很有可读性。

让我们面对现实吧:类c语言中的强制转换操作符在可读性方面相当糟糕。我希望它更好,如果c#采用Javascript语法:

object o = 1;
int i = int(o);

或者定义一个to操作符,相当于as的强制转换:

object o = 1;
int i = o to int;

我认为as关键字可以看作是样式更优雅的版本 dynamic_cast来自c++。

99%的情况下,当我使用“as”时,我不确定实际的对象类型是什么

var x = obj as T;
if(x != null){
 //x was type T!
}

我不想捕捉显式的强制转换异常,也不想使用"is"进行两次强制转换:

//I don't like this
if(obj is T){
  var x = (T)obj; 
}

使用“as”的一个原因是:

T t = obj as T;
 //some other thread changes obj to another type...
if (t != null) action(t); //still works

而不是(坏代码):

if (obj is T)
{
     //bang, some other thread changes obj to another type...
     action((T)obj); //InvalidCastException
}

恕我直言,当与空检查结合在一起时是有意义的:

var y = x as T;
if (y != null)
    y.SomeMethod();