使用“as”是有意义的,而不是一个cast,即使没有null检查? [英] Does it make sense to use "as" instead of a cast even if there is no null check?

查看:164
本文介绍了使用“as”是有意义的,而不是一个cast,即使没有null检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在开发博客,在线代码示例和(最近)甚至一本书,我一直绊住这样的代码:

In development blogs, online code examples and (recently) even a book, I keep stumbling about code like this:

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

或更糟的是:

(x as T).SomeMethod();

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

That doesn't make sense to me. If you are sure that x is of type T, you should use a direct cast: (T)x. If you are not sure, you can use as but need to check for null before performing some operation. All that the above code does is to turn a (useful) InvalidCastException into a (useless) NullReferenceException.

我是唯一一个认为这是公开滥用作为关键字的人吗?

Am I the only one who thinks that this a blatant abuse of the as keyword? Or did I miss something obvious and the above pattern actually makes sense?

推荐答案

你的理解是真的。这听起来像试图微观优化我。当您确定类型时,应使用正常投射。除了产生更明智的异常之外,它也快速失败。如果你对你对类型的假设错了,你的程序会立即失败,你可以立即看到失败的原因,而不是等待 NullReferenceException ArgumentNullException 或甚至在将来某个时候是一个逻辑错误。一般来说, as 表达式后面没有 null 检查某处是代码气味。

Your understanding is true. That sounds like trying to micro-optimize to me. You should use a normal cast when you are sure of the type. Besides generating a more sensible exception, it also fails fast. If you're wrong about your assumption about the type, your program will fail immediately and you'll be able to see the cause of failure immediately rather than waiting for a NullReferenceException or ArgumentNullException or even a logical error sometime in the future. In general, an as expression that's not followed by a null check somewhere is a code smell.

另一方面,如果你不确定该转换并期望它失败,你应该使用作为而不是正常cast包含一个 try-catch 块。此外,建议在类型检查之后使用作为。而不是:

On the other hand, if you are not sure about the cast and expect it to fail, you should use as instead of a normal cast wrapped with a try-catch block. Moreover, use of as is recommended over a type check followed by a cast. Instead of:

if (x is SomeType)
   ((SomeType)x).SomeMethod();

会产生 isinst 说明 关键字和 castclass 说明(有效地执行演员两次),您应该使用:

which generates an isinst instruction for the is keyword, and a castclass instruction for the cast (effectively performing the cast twice), you should use:

var v = x as SomeType;
if (v != null)
    v.SomeMethod();

这只会生成 isinst 指令。前一种方法在多线程应用程序中具有潜在的缺陷,因为竞争条件可能导致变量在检查成功并且在投射行失败后更改其类型。后一种方法不容易出现此错误。

This only generates an isinst instruction. The former method has a potential flaw in multithreaded applications as a race condition might cause the variable to change its type after the is check succeeded and fail at the cast line. The latter method is not prone to this error.

以下解决方案不推荐用于生产代码。如果你真的讨厌这样一个基本的结构在C#,你可以考虑切换到VB或一些其他语言。

如果一个人绝望讨厌cast语法,他/她可以写一个扩展方法来模拟转换:

In case one desperately hates the cast syntax, he/she can write an extension method to mimic the cast:

public static T To<T>(this object o) { // Name it as you like: As, Cast, To, ...
    return (T)o;
}

并使用整洁的[?]语法:

and use a neat[?] syntax:

obj.To<SomeType>().SomeMethod()

这篇关于使用“as”是有意义的,而不是一个cast,即使没有null检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆