我注意到Resharper建议我转过身:
if (myObj.myProp is MyType)
{
...
}
进入这个:
var myObjRef = myObj.myProp as MyType;
if (myObjRef != null)
{
...
}
为什么会建议这种变化?我已经习惯了Resharper建议优化更改和代码减少更改,但这感觉就像它想要我的单一陈述并将其转换为双线程 .
根据MSDN:
如果满足以下两个条件,则表达式求值为true:expression不为null . 表达式可以转换为类型 . 也就是说,形式(类型)(表达式)的强制转换表达式将在不抛出异常的情况下完成 .
我是误读了,或者不是 is
只是在一行中进行完全相同的检查,而不需要为空检查显式创建另一个局部变量?
7 回答
因为只有一个演员 . 比较一下:
对此:
C#7.0使用pattern matching支持更紧凑的语法:
目前还没有关于皮带下面究竟发生了什么的信息 . 看看这个例子:
这转换为以下IL:
这里重要的是
isinst
和castclass
电话 - 两者都相对昂贵 . 如果将其与替代方案进行比较,您可以看到它只进行isinst
检查:另外值得一提的是,值类型将使用
unbox.any
而不是castclass
:但请注意,这不一定转化为更快的结果,因为我们可以看到here . 自从问到这个问题后,似乎有了一些改进:演员似乎表现得和以前一样快,但是
as
和linq
现在快了大约3倍 .最好的选择是使用模式匹配:
Resharper警告:
"Type check and direct cast can be replaced with try cast and check for null"
两者都有效,这取决于你的代码如何更适合你 . 就我而言,我只是忽略了这个警告:
在我的代码第二种方式是更长和更差的性能 .
对我来说,这似乎取决于它将成为那种类型的可能性 . 如果对象在大多数时间属于那种类型,那么在前面进行渲染肯定会更有效 . 如果只是偶尔使用那种类型,那么先用is检查可能更为理想 .
与类型检查的成本相比,创建局部变量的成本非常微不足道 .
可读性和范围对我来说通常是更重要的因素 . 我不同意ReSharper,仅仅因为这个原因使用“is”运算符;如果这是一个真正的瓶颈,请稍后优化 .
(我假设你在这个函数中只使用
myObj.myProp is MyType
一次)它应该建议第二个变化:
成
与原始代码相比,这可以保存属性访问和转换 . 但是只有在将
is
更改为as
之后才有可能 .我想这是制作myObj.myProp的强类型版本,即myObjRef . 然后,当您在块中引用此值时,应该使用此方法,而不必进行强制转换 .
例如,这个:
比这更好: