为匿名方法生成 IL

发布于 2024-11-25 20:27:04 字数 1865 浏览 3 评论 0原文

我想为多线程应用程序生成 IL。作为第一步 我编写了一个简单的应用程序,并使用 ILSpy 检查并生成了 IL。

public class ThreadTesting
{
    public static void Main()
    {
        Thread thread = new Thread(() => Print("Hello from t!"));
        thread.Start();
    }

    public static void Print(string message)
    {
        Console.WriteLine(message);
    }
}
.method public hidebysig static 
    void Main () cil managed 
{
    // Method begins at RVA 0x2060
    // Code size 46 (0x2e)
    .maxstack 3
    .entrypoint
    .locals init (
        [0] class [mscorlib]System.Threading.Thread
    )

    IL_0000: nop
    IL_0001: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1'
    IL_0006: brtrue.s IL_001b

    IL_0008: ldnull
    IL_0009: ldftn void ThreadTesting::'<Main>b__0'()
    IL_000f: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, native int)
    IL_0014: stsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1'
    IL_0019: br.s IL_001b

    IL_001b: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1'
    IL_0020: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
    IL_0025: stloc.0
    IL_0026: ldloc.0
    IL_0027: callvirt instance void [mscorlib]System.Threading.Thread::Start()
    IL_002c: nop
    IL_002d: ret
} // end of method ThreadTesting::Main

我能够使用 System.Reflection.Emit 生成上述大部分 IL 代码 命名空间。

不幸的是我不知道如何生成 使用 System.Reflection.Emit 执行以下 IL 代码。

IL_0001: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS$<>9__CachedAnonymousMethodDelegate1'

有人可以帮我弄清楚吗 如何为匿名方法生成 IL?

I want to generate IL for a multithreaded application. As the first step
I wrote a simple application and inspected, generated IL using ILSpy.

public class ThreadTesting
{
    public static void Main()
    {
        Thread thread = new Thread(() => Print("Hello from t!"));
        thread.Start();
    }

    public static void Print(string message)
    {
        Console.WriteLine(message);
    }
}
.method public hidebysig static 
    void Main () cil managed 
{
    // Method begins at RVA 0x2060
    // Code size 46 (0x2e)
    .maxstack 3
    .entrypoint
    .locals init (
        [0] class [mscorlib]System.Threading.Thread
    )

    IL_0000: nop
    IL_0001: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS
lt;>9__CachedAnonymousMethodDelegate1'
    IL_0006: brtrue.s IL_001b

    IL_0008: ldnull
    IL_0009: ldftn void ThreadTesting::'<Main>b__0'()
    IL_000f: newobj instance void [mscorlib]System.Threading.ThreadStart::.ctor(object, native int)
    IL_0014: stsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS
lt;>9__CachedAnonymousMethodDelegate1'
    IL_0019: br.s IL_001b

    IL_001b: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS
lt;>9__CachedAnonymousMethodDelegate1'
    IL_0020: newobj instance void [mscorlib]System.Threading.Thread::.ctor(class [mscorlib]System.Threading.ThreadStart)
    IL_0025: stloc.0
    IL_0026: ldloc.0
    IL_0027: callvirt instance void [mscorlib]System.Threading.Thread::Start()
    IL_002c: nop
    IL_002d: ret
} // end of method ThreadTesting::Main

I was able to generate most of the above IL codes using System.Reflection.Emit
namespace.

Unfortunate I couldn't figure out how to generate
following IL code using System.Reflection.Emit.

IL_0001: ldsfld class [mscorlib]System.Threading.ThreadStart ThreadTesting::'CS
lt;>9__CachedAnonymousMethodDelegate1'

So can somebody help me to figure out
how to generate IL for Anonymous methods?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧伤还要旧人安 2024-12-02 20:27:04

该 IL 只是编译器缓存委托实例的方式 - 它不是方法本身的一部分。如果您使用的是 DynamicMethod (您可能应该使用),则只需调用 CreateDelegate({您的委托类型}),将其转换为您所需的委托类型(可能是 ThreadStart),并将(类型化)委托实例存储在任何地方。

That IL is simply the way the compiler caches the delegate instance - it isn't part of the method itself. If you are using DynamicMethod (which you probably should be) then just call CreateDelegate({your delegate type}), cast it to your desired delegate type (probably ThreadStart), and store the (typed) delegate instance anywhere.

卖梦商人 2024-12-02 20:27:04

IL 中没有“匿名方法”这样的概念。 C# 编译器所做的就是创建具有难以形容的名称 (

b__0) 的普通方法和一个静态字段来缓存该方法的委托 (CS$<>9__CachedAnonymousMethodDelegate1 )。

你应该做什么取决于你想做什么。如果您不想缓存委托,则不必这样做,您可以创建它,它会在一定程度上简化您的代码。

如果将匿名方法转换为普通方法,并在 ILSpy 中查看,您将看到简化的 IL(没有 ldsfld),并且可以生成它。

The is no such concept as “anonymous method” in IL. What the C# compiler does is to create normal method with an unspeakable name (<Main>b__0) and a static field to cache a delegate to the method (CS$<>9__CachedAnonymousMethodDelegate1).

What you should do depends on what you want to do. If you don't want to cache the delegate, you don't have to and you can create it and it will simplify your code somewhat.

If you convert the anonymous method into normal method, and look at that in ILSpy, you will see the simplified IL (without ldsfld) and you can generate that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文