CIL反汇编涉及三元表达式的函数参数

时间:2016-01-12 09:07:26

标签: c# cil disassembly

我在参数的CIL反汇编中遇到了WriteLine()调用:

FileInfo path = new FileInfo(@"c:\a.txt");
Console.WriteLine("prefix: " + path != null ? path.FullName : "null");

CIL dissasembly

.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 //基于之前的返回值进行分支

  • 为什么Concat使用path作为参数而不是path.FullName来调用?
  • 如果Concat的第一个参数为nullnull会返回+吗?怎么样 编译器知道吗? (如果我将plus(string, string)替换为我自己的WriteLine,那么 拆卸到我宁愿期待的东西。)

请您解释,反汇编如何处理三元参数以及对 static void Main(string[] args) { string sourceFolder = @"C:\dom"; string searchWord = "&#x9"; string regexPattern = @"@([A-Za-z0-9\-_]+).\&#x9"; List<string> allFiles = new List<string>(); AddFileNamesToList(sourceFolder, allFiles); foreach (string fileName in allFiles) { string contents = File.ReadAllText(fileName); if (showMatch(contents, regexPattern)) { if (contents.Contains(searchWord)) { Console.WriteLine(fileName); } } } Console.WriteLine(" "); System.Console.ReadKey(); } private static bool showMatch(string text, string expr) { Console.WriteLine("The Expression: " + expr); MatchCollection mc = Regex.Matches(text, expr); foreach (Match m in mc) { Console.WriteLine(m); } return mc.Count > 0; } public static void AddFileNamesToList(string sourceDir, List<string> allFiles) { string[] fileEntries = Directory.GetFiles(sourceDir); foreach (string fileName in fileEntries) { allFiles.Add(fileName); } //Recursion string[] subdirectoryEntries = Directory.GetDirectories(sourceDir); foreach (string item in subdirectoryEntries) { // Avoid "reparse points" if ((File.GetAttributes(item) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint) { AddFileNamesToList(item, allFiles); } } } 的调用?

1 个答案:

答案 0 :(得分:8)

这不是反汇编的问题,而是运算符优先级的问题。

您的表达式评估为

("prefix: " + path != null) ? path : "null";

不是

"prefix: " + (path != null ? path : "null");
正如你所期待的那样。只需正确使用括号,你就可以了:)

事实上,它是编译器的一部分错过了“优化” - 因为string.Concat("prefix: ", whatever) 永远不会为空,你总是获得{{ 1}}。当然,只评估其中一个选项的三元组几乎肯定是一个错误,所以......