在开发博客,在线代码示例和(最近)甚至是一本书中,我一直在寻找像这样的代码: 多线程
var y = x as T; y.SomeMethod();
或者更糟糕的是: 优化
(x as T).SomeMethod();
这对我来讲没有意义。 若是您肯定x
是T
类型,则应使用直接强制转换: (T)x
。 若是您不肯定,可使用as
但须要在执行某些操做以前检查null
。 以上代码所作的就是将(有用的) InvalidCastException
为(无用的) NullReferenceException
。 this
我是惟一一个认为这是对as
关键字的公然滥用的人吗? 仍是我错过了一些明显的东西,上面的模式实际上有意义? spa
你的理解是真的。 这听起来像是试图对我进行微观优化。 当您肯定类型时,应该使用普通的强制转换。 除了产生更明智的例外,它也会快速失败。 若是你对类型的假设错了,你的程序将当即失败,你将可以当即看到失败的缘由,而不是等待NullReferenceException
或ArgumentNullException
,甚至在未来的某个时候等待逻辑错误。 在通常状况下, as
表达式,表示后面没有null
支票的地方是一个代码味道。 线程
另外一方面,若是您不肯定转换并指望它失败,您应该使用as
而不是使用try-catch
块包装的普通转换。 此外,建议使用as
类型检查,而后进行强制转换。 代替: code
if (x is SomeType) ((SomeType)x).SomeMethod();
它为is
关键字生成一个isinst
指令 ,并为一个cast(有效地执行两次转换)的castclass
指令 ,你应该使用: 对象
var v = x as SomeType; if (v != null) v.SomeMethod();
这只会生成一个isinst
指令。 前一种方法在多线程应用中的潜在缺陷的竞争条件可能致使要改变的变量的类型后is
勾选成功,并在投行失败。 后一种方法不容易出现这种错误。 开发
建议不要在生产代码中使用如下解决方案。 若是你真的讨厌C#中这样一个基本的构造,你能够考虑切换到VB或其余语言。 get
若是一我的极度讨厌强制转换语法,他/她能够编写一个扩展方法来模仿强制转换: 博客
public static T To<T>(this object o) { // Name it as you like: As, Cast, To, ... return (T)o; }
并使用整洁的[?]语法:
obj.To<SomeType>().SomeMethod()
恕我直言, as
刚刚有意义当与联合null
检查:
var y = x as T; if (y != null) y.SomeMethod();
直接投射比as
关键字须要一对括号。 所以,即便在您100%肯定类型是什么的状况下,它也能够减小视觉混乱。
可是就异常事项达成了一致意见。 但至少对我来讲,最用途as
归结为检查null
以后,我以为这比捕获异常漂亮。
当我使用“as”时,99%的时间是我不肯定实际对象类型是何时
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
关键字能够被认为是来自C ++的dynamic_cast
的更优雅的版本。