Hot*_*otN 102 .net c# resharper casting
我注意到Resharper建议我转过身:
if (myObj.myProp is MyType)
{
...
}
Run Code Online (Sandbox Code Playgroud)
进入这个:
var myObjRef = myObj.myProp as MyType;
if (myObjRef != null)
{
...
}
Run Code Online (Sandbox Code Playgroud)
为什么会建议这种变化?我已经习惯了Resharper建议优化更改和代码减少更改,但这感觉就像它想要我的单一陈述并将其转换为双线程.
根据MSDN:
一个是 表达式如果两个满足以下条件的值为true:
表达式不为空.表达式可以转换为类型.也就是说,表单的强制转换表达式将在
(type)(expression)不抛出异常的情况下完成.
我是否误读了,或者没有is完全相同的检查,只需要在一行中而不需要为空检查显式创建另一个局部变量?
Jef*_*f E 137
因为只有一个演员.比较一下:
if (myObj.myProp is MyType) // cast #1
{
var myObjRef = (MyType)myObj.myProp; // needs to be cast a second time
// before using it as a MyType
...
}
Run Code Online (Sandbox Code Playgroud)
对此:
var myObjRef = myObj.myProp as MyType; // only one cast
if (myObjRef != null)
{
// myObjRef is already MyType and doesn't need to be cast again
...
}
Run Code Online (Sandbox Code Playgroud)
C#7.0支持使用模式匹配的更紧凑的语法:
if (myObj.myProp is MyType myObjRef)
{
...
}
Run Code Online (Sandbox Code Playgroud)
最好的选择是使用模式匹配:
if (value is MyType casted){
//Code with casted as MyType
//value is still the same
}
//Note: casted can be used outside (after) the 'if' scope, too
Run Code Online (Sandbox Code Playgroud)
目前还没有关于皮带下面究竟发生了什么的信息.看看这个例子:
object o = "test";
if (o is string)
{
var x = (string) o;
}
Run Code Online (Sandbox Code Playgroud)
这转换为以下IL:
IL_0000: nop
IL_0001: ldstr "test"
IL_0006: stloc.0 // o
IL_0007: ldloc.0 // o
IL_0008: isinst System.String
IL_000D: ldnull
IL_000E: cgt.un
IL_0010: stloc.1
IL_0011: ldloc.1
IL_0012: brfalse.s IL_001D
IL_0014: nop
IL_0015: ldloc.0 // o
IL_0016: castclass System.String
IL_001B: stloc.2 // x
IL_001C: nop
IL_001D: ret
Run Code Online (Sandbox Code Playgroud)
这里重要的是isinst和castclass电话 - 两者都相对昂贵.如果将其与替代方案进行比较,您可以看到它只进行isinst检查:
object o = "test";
var oAsString = o as string;
if (oAsString != null)
{
}
IL_0000: nop
IL_0001: ldstr "test"
IL_0006: stloc.0 // o
IL_0007: ldloc.0 // o
IL_0008: isinst System.String
IL_000D: stloc.1 // oAsString
IL_000E: ldloc.1 // oAsString
IL_000F: ldnull
IL_0010: cgt.un
IL_0012: stloc.2
IL_0013: ldloc.2
IL_0014: brfalse.s IL_0018
IL_0016: nop
IL_0017: nop
IL_0018: ret
Run Code Online (Sandbox Code Playgroud)
另外值得一提的是,值类型将使用unbox.any而不是castclass:
object o = 5;
if (o is int)
{
var x = (int)o;
}
IL_0000: nop
IL_0001: ldc.i4.5
IL_0002: box System.Int32
IL_0007: stloc.0 // o
IL_0008: ldloc.0 // o
IL_0009: isinst System.Int32
IL_000E: ldnull
IL_000F: cgt.un
IL_0011: stloc.1
IL_0012: ldloc.1
IL_0013: brfalse.s IL_001E
IL_0015: nop
IL_0016: ldloc.0 // o
IL_0017: unbox.any System.Int32
IL_001C: stloc.2 // x
IL_001D: nop
IL_001E: ret
Run Code Online (Sandbox Code Playgroud)
但请注意,这并不一定意味着更快的结果,我们可以在这里看到.目前似乎已经改善,因为该问题是尽管问:铸件看起来就像他们曾经是,但要快速执行as和linq现在大约快3倍.
| 归档时间: |
|
| 查看次数: |
40116 次 |
| 最近记录: |