为什么要在使用"as"时转换引用类型?

CJ7*_*CJ7 6 c# casting

可能重复:
转换:(NewType)与Object作为NewType

在C#中,为什么要在使用"as"时转换引用类型?

铸造可以产生异常,而"as"将null在铸造失败时进行评估.

在所有情况下,"as"是否更容易使用引用类型?

例如:

MyObject as DataGridView
Run Code Online (Sandbox Code Playgroud)

而不是,

(DataGridView)MyObject
Run Code Online (Sandbox Code Playgroud)

Dan*_*ker 9

考虑以下备选方案:

Foo(someObj as SomeClass);
Run Code Online (Sandbox Code Playgroud)

和:

Foo((SomeClass)someObj);
Run Code Online (Sandbox Code Playgroud)

由于someObj是错误的类型,第一个版本传递nullFoo.一段时间后,这会导致NullReferenceException被抛出.多久以后?取决于什么Foo.它可能会存储null在一个字段中,然后几分钟后它会被一些期望它为非的代码访问null.

但是对于第二个版本,您会立即发现问题.

为什么要修复bug更难?

更新

OP在评论中询问:是不是更容易使用as,然后nullif声明中检查?

如果null是意外的并且是调用者中的错误的证据,您可以说:

SomeClass c = someObj as SomeClass;
if (c == null)
{
    // hmm...
}
Run Code Online (Sandbox Code Playgroud)

你在那个if街区做什么?有两种通用解决方案.一种是抛出异常,因此调用者有责任处理他们的错误.在这种情况下,写起来肯定更简单:

SomeClass c = (SomeClass)someObj;
Run Code Online (Sandbox Code Playgroud)

它只是简单地节省了您手动编写if/ throw逻辑.

还有另一种选择.如果你有一个"库存"实现SomeClass,你很乐意使用没有更好的可用(可能它没有什么方法,或返回"空"值等),那么你可以这样做:

SomeClass c = (someObj as SomeClass) ?? _stockImpl;
Run Code Online (Sandbox Code Playgroud)

这将确保c永远不会null.但这真的更好吗?如果来电者有错误怎么办?你不想帮助发现bug吗?通过交换默认对象,您可以伪装该错误.这听起来像是一个有吸引力的想法,直到你浪费一周的时间来追踪一个bug.

(在某种程度上,这模仿了Objective-C的行为,其中任何使用null引用的尝试都将永远不会抛出;它只是默默地做什么.)


Ars*_*eny 2

运算符“as”仅适用于引用类型。