涉及三元表达式的函数参数的 CIL 反汇编
CIL disassembly of a function parameter involving a ternary expression
我努力将参数的 CIL 反汇编到 WriteLine()
调用:
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
// 根据之前的return值进行分支
- 为什么调用
Concat
时使用 path
作为参数而不是 path.FullName
?
- 如果第一个参数是
null
,是否Concat
returnnull
?如何
编译器知道吗? (如果我将 +
替换为我自己的 plus(string, string)
,则
反汇编成我更愿意期待的东西。)
能否请您解释一下,反汇编如何处理三元参数以及对 WriteLine
的调用?
不是反汇编的问题,是运算符优先级的问题
您的表达式被评估为
("prefix: " + path != null) ? path : "null";
不如
"prefix: " + (path != null ? path : "null");
如你所料。只要正确使用括号就可以了:)
事实上,编译器的一部分遗漏了 "optimization" - 因为 string.Concat("prefix: ", whatever)
可以 永远不会 为 null,你将 总是得到path.FullName
。当然,只计算其选项之一的三元组几乎肯定是一个错误,所以...
我努力将参数的 CIL 反汇编到 WriteLine()
调用:
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
// 根据之前的return值进行分支
- 为什么调用
Concat
时使用path
作为参数而不是path.FullName
? - 如果第一个参数是
null
,是否Concat
returnnull
?如何 编译器知道吗? (如果我将+
替换为我自己的plus(string, string)
,则 反汇编成我更愿意期待的东西。)
能否请您解释一下,反汇编如何处理三元参数以及对 WriteLine
的调用?
不是反汇编的问题,是运算符优先级的问题
您的表达式被评估为
("prefix: " + path != null) ? path : "null";
不如
"prefix: " + (path != null ? path : "null");
如你所料。只要正确使用括号就可以了:)
事实上,编译器的一部分遗漏了 "optimization" - 因为 string.Concat("prefix: ", whatever)
可以 永远不会 为 null,你将 总是得到path.FullName
。当然,只计算其选项之一的三元组几乎肯定是一个错误,所以...