涉及三元表达式的函数参数的CIL反汇编
本文关键字:函数 参数 CIL 反汇编 表达式 三元 | 更新日期: 2023-09-27 18:30:00
我很难在中对WriteLine()
调用的参数进行CIL反汇编
FileInfo path = new FileInfo(@"c:'a.txt");
Console.WriteLine("prefix: " + path != null ? path.FullName : "null");
CIL分解
.locals init (
[0] class [mscorlib]System.IO.FileInfo path
)
// ...
IL_000c: ldstr "prefix: "
IL_0011: ldloc.0
IL_0012: call string [mscorlib]System.String::Concat(object, object)
IL_0017: brtrue.s IL_0020
IL_0019: ldstr "null"
IL_001e: br.s IL_0026
IL_0020: ldloc.0
IL_0021: callvirt instance string [mscorlib]System.IO.FileSystemInfo::get_FullName()
IL_0026: call void [mscorlib]System.Console::WriteLine(string)
在我看来,首先调用Concat
,然后才调用三元操作员评估。特别是:
IL_0012
似乎调用了Concat("prefix", path)
,IL_0012
brtrue.s IL_0020
//基于先前返回值的分支
- 为什么用
path
而不是path.FullName
作为参数来调用Concat
- 如果
Concat
的第一个参数是null
,它是否返回null
?如何编译器知道吗?(如果我用自己的plus(string, string)
替换+
拆卸成我更期待的东西。)
你能解释一下,反汇编是如何处理三元参数和对WriteLine
的调用的吗?
这不是反汇编的问题,而是运算符优先级的问题。
您的表达式被评估为
("prefix: " + path != null) ? path : "null";
不作为
"prefix: " + (path != null ? path : "null");
正如你所期望的那样。只要正确使用括号,你就可以了:)
事实上,这是编译器遗漏的"优化"部分——由于string.Concat("prefix: ", whatever)
可以从不为null,因此您将始终获得path.FullName
。当然,一个只计算其中一个选项的三进制几乎肯定是一个错误,所以…