如果 Reflector 生成条件,则很奇怪

Strange if condition generated by Reflector

提问人:Water Cooler v2 提问时间:5/13/2017 更新时间:5/13/2017 访问量:100

问:

我时不时地会写一个程序来提醒自己一些事情,所以这是我昨天写的,当时发生了一些奇怪的事情。

原始来源

using System;
using System.Threading;

namespace TestThreadFunctions
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "Main thread";

            var t = JoiningAnAlreadyCompletedThread();

            JoiningIsIdempotent(t);

            Console.ReadKey();
        }

        static Thread JoiningAnAlreadyCompletedThread()
        {
            Thread t = new Thread(() =>
            {
                Console.WriteLine($"{Thread.CurrentThread.Name} ({Thread.CurrentThread.ManagedThreadId}): I'm done now.\n");
            })
            { Name = "Worker 1" };

            t.Start();

            // Give a long time-out so we know that the 
            // current thread did not wait the entire time-out
            // or that it didn't wait at all because the thread
            // we are joining on has already completed.
            t.Join(10000);

            Console.WriteLine($"{Thread.CurrentThread.Name} ({Thread.CurrentThread.ManagedThreadId}): I just joined on another thread that I knew was already completed even before I joined. See nothing happened. .NET doesn't punish you for joining a thread that has already completed, unlike POSIX systems, which do.\n");

            return t;
        }

        static void JoiningIsIdempotent(Thread threadToJoinOn)
        {
            Console.WriteLine($"{Thread.CurrentThread.Name} ({Thread.CurrentThread.ManagedThreadId}): I am about to join a thread that I already joined with earlier. I want to see if joining is idempotent.\n");

            // Joining is idempotent
            threadToJoinOn.Join();

            Console.WriteLine($"{Thread.CurrentThread.Name} ({Thread.CurrentThread.ManagedThreadId}): I just finished joining with a thread that I already joined with earlier. See! nothing happened. Joining is idempotent.\n");
        }
    }
}

当我在 Reflector 中查找程序时,它在方法开始时有这个奇怪的情况,如下所示:ifJoiningAnAlreadyCompletedThread

private static Thread JoiningAnAlreadyCompletedThread()
{
    if (<>c.<>9__1_0 == null)
    {
        ThreadStart start1 = <>c.<>9__1_0;
    }

    ...
}

我读了几遍,只是为了确认我没有遗漏什么。这太奇怪了,它什么也没做。

为了完整起见,这里是 Reflector 的完全反编译程序。

Reflector 反编译源

internal class Program
{
    // Methods
    private static Thread JoiningAnAlreadyCompletedThread()
    {
        if (<>c.<>9__1_0 == null)
        {
            ThreadStart start1 = <>c.<>9__1_0;
        }
        Thread thread1 = new Thread(<>c.<>9__1_0 = new ThreadStart(<>c.<>9.<JoiningAnAlreadyCompletedThread>b__1_0)) {
            Name = "Worker 1"
        };
        Thread t = thread1;
        t.Start();
        t.Join(0x2710);
        Console.WriteLine(string.Format("{0} ({1}): I just joined on another thread that I knew was already completed even before I joined. See nothing happened. .NET doesn't punish you for joining a thread that has already completed, unlike POSIX systems, which do.\n", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId));
        return t;
    }

    private static void JoiningIsIdempotent(Thread threadToJoinOn)
    {
        Console.WriteLine(string.Format("{0} ({1}): I am about to join a thread that I already joined with earlier. I want to see if joining is idempotent.\n", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId));
        threadToJoinOn.Join();
        Console.WriteLine(string.Format("{0} ({1}): I just finished joining with a thread that I already joined with earlier. See! nothing happened. Joining is idempotent.\n", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId));
    }

    private static void Main(string[] args)
    {
        Thread.CurrentThread.Name = "Main thread";
        JoiningIsIdempotent(JoiningAnAlreadyCompletedThread());
        Console.ReadKey();
    }

    // Nested Types
    [Serializable, CompilerGenerated]
    private sealed class <>c
    {
        // Fields
        public static readonly Program.<>c <>9 = new Program.<>c();
        public static ThreadStart <>9__1_0;

        // Methods
        internal void <JoiningAnAlreadyCompletedThread>b__1_0()
        {
            Console.WriteLine(string.Format("{0} ({1}): I'm done now.\n", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId));
        }
    }
}

我在 IL Spy 中查找了相同的来源,它并没有做这种奇怪的事情。它没有这种什么也没做。if

IL Spy 反编译

// TestThreadFunctions.Program
private static Thread JoiningAnAlreadyCompletedThread()
{
    ThreadStart arg_20_0;
    if ((arg_20_0 = Program.<>c.<>9__1_0) == null)
    {
        arg_20_0 = (Program.<>c.<>9__1_0 = new ThreadStart(Program.<>c.<>9.<JoiningAnAlreadyCompletedThread>b__1_0));
    }
    Thread thread = new Thread(arg_20_0)
    {
        Name = "Worker 1"
    };
    thread.Start();
    thread.Join(10000);
    Console.WriteLine(string.Format("{0} ({1}): I just joined on another thread that I knew was already completed even before I joined. See nothing happened. .NET doesn't punish you for joining a thread that has already completed, unlike POSIX systems, which do.\n", Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId));
    return thread;
}

所以,我想我不知道这里的问题是什么。也许是“Reflector 为什么要这样做?

然后答案可能是,“嗯,反编译很困难”,我理解。

所以,我真的不知道问题是什么,但我想我只是想分享我的困惑。

如果你真的在这里看到一个有合理解释的问题,我很想知道为什么 Reflector 会这样做。

否则,我知道这个问题会被否决并关闭。

C# 反编译 反射器 .net-reflector

评论

1赞 Samvel Petrosov 5/13/2017
我可以补充一点,dnSpy 也没有这样做 d1ro8r1rbfn3jf.cloudfront.net/ms_125222/......
0赞 Water Cooler v2 5/13/2017
耶!另一个开源反编译器。
0赞 Water Cooler v2 5/13/2017
dnSpy 和 IL Spy 的绰号非常相似。必须查找源代码以查看一个是否是另一个的分支。
0赞 Samvel Petrosov 5/13/2017
Telerik 反编译结果更具可读性,更接近原始 imgur.com/a/yZQiM
0赞 Water Cooler v2 5/13/2017
好。dotPeek也是如此。它显示了我们用文件名编写的相同源代码。不知道它从哪里拉出来。

答: 暂无答案