使用“as"有意义吗?即使没有空检查而不是强制转换?

Does it make sense to use quot;asquot; instead of a cast even if there is no null check?(使用“as有意义吗?即使没有空检查而不是强制转换?)
本文介绍了使用“as"有意义吗?即使没有空检查而不是强制转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.如果不确定,可以使用 as,但需要在执行某些操作之前检查 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.

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

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?

推荐答案

你的理解是对的.这听起来像是试图对我进行微优化.当您确定类型时,您应该使用正常转换.除了产生更合理的异常之外,它也很快失败.如果您对类型的假设有误,您的程序将立即失败,您将能够立即看到失败的原因,而不是等待 NullReferenceExceptionArgumentNullException,甚至将来某个时候出现逻辑错误.一般来说,一个 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.

另一方面,如果您不确定强制转换并期望它失败,您应该使用 as 而不是使用 try-catch 阻止.此外,建议使用 as 而不是类型检查,然后进行强制转换.而不是:

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<is 关键字的/code> 指令 和 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 指令.前一种方法在多线程应用程序中存在潜在缺陷,因为竞态条件可能会导致变量在 is 检查成功后更改其类型并在强制转换行失败.后一种方法不容易出现这个错误.

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 或其他语言.

The following solution is not recommended for use in production code. If you really hate such a fundamental construct in C#, you might consider switching to VB or some other language.

如果一个人非常讨厌强制转换语法,他/她可以编写一个扩展方法来模仿强制转换:

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"有意义吗?即使没有空检查而不是强制转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)