为什么ReSharper推荐使用"as"关键字而不是"is"关键字?

4
我使用Resharper 8,当我写下

时。
if (sender is Button) 

Resharper 建议使用 as 关键字并将其更改为:

Button button = sender as Button;
if (button != null)

有任何特别的原因吗?

使用as比使用is更好吗?或者在这种情况下,as更好吗?


1
我假设(我没有Resharper)这是因为您稍后要使用“Button”。 “as”将其转换并检查是否可以转换。 “is”只是检查它,无论如何都必须进行转换。 - Tim Schmelter
4个回答

4

as在后续使用表达式时可能更好;如果不需要,则is同样适用。例如:

if (sender is Button) {
    Button button = (Button)sender;  // just use `as`, as suggested
    button.Push();

我认为ReSharper只会在可以消除重复强制转换的情况下发出警告/提示,例如:

话虽如此,我使用这种结构

Button button;
if ((button = sender as Button) != null) {
    button.Push();

为确保变量在条件中初始化且仅在条件中初始化,这会将as的应用延迟到适当的条件表达式上,并允许C#/ReSharper检测一些不正确的[未初始化]变量使用情况。
另请参阅:

CLR中的强制转换与使用“as”关键字 - Jon的答案使用"is /(cast)"配对作为一个“不要这样做”,并提出了共享和字段与属性访问之间的问题。还讨论了性能和“is”与“as”的区别。

以及一个重复的哪种代码更好:使用“as”还是“is”?,附有其他更好的相关链接。


2
还要注意,在C# 6中,我们将能够将Button的声明移动到if本身内部,进一步改进它:if ((Button button = sender as Button) != null) { - Matthew Watson

3

我认为这是因为as关键字一次性完成了类型检查和转换。因此,如果您稍后使用发送器,就不需要进行类型转换。


就是这样了 - 尽管JIT或者编译器可以优化它,但据我所知并没有这样做,因此AS格式可以节省一个转换。 - TomTom

3
"as"运算符用于在兼容类型之间执行转换。而"is"运算符用于检查对象的运行时类型是否与给定类型兼容。
因此,我认为使用as将是更好的选择,因为as运算符尝试将对象强制转换为特定类型,并在失败时返回null。
您还可以查看Eric Liperts关于“{{link1:Is is as or is as is?}}”的博客。
然而,在实践中,CLR提供了isinst指令,其具有类似于as的功能。因此,我们有一个实现as语义相当不错的指令,可以从中构建is的实现。简而言之,法律上is is is,as is as is is,但事实上is is as,as is isinst。

并且“as”和“cast”运算符有什么区别?

来自这里:

'as'优于'is'的优点

对于is运算符,要进行类型转换,我们需要执行两个步骤:

  1. 使用is检查类型
  2. 如果为真,则进行类型转换

实际上,这会影响性能,因为每次CLR都会遍历继承层次结构,检查每个基类型是否与指定类型匹配。 为了避免这种情况,应该使用as,它可以在一步中完成。只有在检查类型时才应使用is运算符。


0

您没有发布所有的代码。我猜在您的代码中,如果发送者是一个按钮,您会将其转换为按钮并对其进行一些操作。如果是这种情况,您做了这个工作两次,一次在if语句中,一次在语句块中。Resharper 建议您只需执行一次并完成它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接