【问题标题】:How to get every line of instruction for invoking method using Reflection C#如何使用反射 C# 获取调用方法的每一行指令
【发布时间】:2014-07-04 11:33:10
【问题描述】:

我正在使用反射 C#。

我的要求是指定方法是使用反射调用,得到以下 方法调用后调用方法的事情。

  1. 评论行
  2. 方法中的执行指令

提前致谢。

【问题讨论】:

  • 这是不可能的。反射与仪器无关。您也无法从中获得 cmets。这也很有趣——你需要这些信息做什么?
  • 评论行?那些没有编译成程序集。谁给你的?可以通过反编译或分析 MSIL 来执行指令,但不能通过反射。
  • 有获取调用栈的API。不知道你在这里找什么。在 Visual Studio 中,您可以使用自动化来获取 CodeClass 和 CodeFunction。
  • 您是否正在寻找summary xml 信息?

标签: c# reflection .net-assembly


【解决方案1】:

你所要求的是不可能的,因为反射不是可以反编译你的程序集的圣杯。

因此,使用 .NET(Vb、C#、...)编写的程序或编译为 IL 或中间语言的程序。

那么,什么是中间语言?

中间语言 (IL) 是一种面向对象的编程语言,旨在供 .NET Framework 的编译器在静态或动态编译为机器代码之前使用。 .NET Framework 使用 IL 生成与机器无关的代码,作为以任何 .NET 编程语言编写的源代码的编译输出。

IL 是一种基于堆栈的汇编语言,可在虚拟机执行期间转换为字节码。它由公共语言基础设施 (CLI) 规范定义。由于 IL 用于自动生成编译代码,因此无需学习其语法。

该术语也称为 Microsoft 中间语言 (MSIL) 或通用中间语言 (CIL)。

示例:

我们来看看下面这个小程序:

using System;

namespace ConsoleApplication1
{
    // Start class.
    class Program
    {
        // Main entry point.
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
   }

}

当你现在使用Telerik JustDecompile之类的时候,你可以查看应用程序的源代码:

使用系统;

namespace ConsoleApplication1
{
    internal class Program
    {
        public Program()
        {
        }

        private static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
        }
    }
}

您会注意到反编译器生成的代码实际上与您最初的不同,但技术相同。

但是添加了一个公共构造函数(即使您没有在类中添加一个,编译器也会添加一个默认构造函数)。 cmets 不见了。

现在,这是为什么呢?这是因为编译后的 exe 文件不包含您的代码,而只包含您翻译成 IL 的代码,而反编译器会将其翻译回 C#。

那么,IL 是什么样子的?

.class private auto ansi beforefieldinit ConsoleApplication1.Program
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor () cil  managed 
    {
        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    }

    .method private hidebysig static void Main (
            string[] args
        ) cil managed 
    {
        .entrypoint
        IL_0000: nop
        IL_0001: ldstr "Hello, World!"
        IL_0006: call void [mscorlib]System.Console::WriteLine(string)
        IL_000b: nop
        IL_000c: ret
    }
}

你看这已经是更接近机器语言的东西了。

所以,我希望这能说明为什么您无法通过反射获取源代码。

【讨论】:

    【解决方案2】:

    这是不可能的。反射与检测无关,它与描述类型、方法等的元数据有关。您也无法从中获取 cmets,因为它们未包含在已编译的程序集中。

    事实上,如果没有非常非常神奇的方法,根本不可能对运行程序集进行如此深入的了解,比如使用Microsoft.Diagnostics.Runtime

    ClrMD 是一组高级 API,用于以与 SOS 调试扩展 (SOS) 相同的方式以编程方式检查 .NET 程序的故障转储。它允许您为您的应用程序编写自动崩溃分析并自动执行许多常见的调试器任务。

    也可以附加到自我进程并在正常工作期间对其进行分析,因此也许可以获得有关仪器的一些信息。但正如我所说 - 这将是神奇的。而且我敢肯定,您根本不需要这样做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      相关资源
      最近更新 更多