0

在 .net 反编译器中,我看不到构造函数的代码。我已经在许多 .net 反编译器中进行了测试,但它们都没有显示构造函数代码。是否有任何反编译器显示该代码。

提前致谢 在此处输入图像描述

4

2 回答 2

4

由 C# 定义的所有 .NET 类型(我不知道 VB.NET 或其他语言是如何做到这一点的,它们可能会做同样的事情,也可能不会)将有一个构造函数。

如果您没有显式添加构造函数,编译器将为您提供一个。

我已经(之前)测试过 JetBrains 的 Telerik 反编译器、Reflector 和 dotPeek,当有代码要显示时,它们都会显示构造函数代码。

这是 dotPeek 1.1 显示的构造函数Tuple<T1, T2>

dotPeek 1.1 反编译的 Tuple<T1, T2> 构造函数

但是,反编译器可能会选择删除构造函数,因为它看不到您的原始源代码,因此它会尝试推断哪种代码会生成您提供给它的 IL。因此,即使您的代码显式地写出一个空的构造函数,它也很可能与编译器在没有它时为您提供的内容 100% 相同,因此反编译器会假设您没有写出一个空的构造函数。

TL;DR:根据MultipleLookupField 构造函数的文档判断,它没有参数。因此,它的唯一目的可能是调用基本构造函数而不是其他任何东西。因此,可能完全没有必要进行反编译,因为可能的情况是源代码中也没有写出。

然而,为了说明所有类都有构造函数,让我们看一些例子。

下面的例子可以在LINQPad中通过执行代码进行测试,然后点击结果上方的 IL 按钮可以看到反编译的 IL。LINQPad 的反编译器(我相信 mono.cecil)不会对同一级别进行这种推断,因此它会显示构造函数。

示例 1:没有构造函数或将放置在构造函数中的代码

void Main()
{
    var t = new Test();
    t.Execute();
}

public class Test
{
    public void Execute()
    {
        Debug.WriteLine("Execute");
    }
}

生成的 IL:

IL_0000:  newobj      UserQuery+Test..ctor
IL_0005:  stloc.0     // t
IL_0006:  ldloc.0     // t
IL_0007:  callvirt    UserQuery+Test.Execute

Test.Execute:
IL_0000:  ldstr       "Execute"
IL_0005:  call        System.Diagnostics.Debug.WriteLine
IL_000A:  ret         

Test..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret     

如您所见,其中有一个构造函数,但它所做的只是从System.Object.

示例 2:添加具有默认值的字符串字段

现在让我们做点别的,将这个字段添加到类中:

public class Test
{
    private string _Value = string.Empty;

    public void Execute()
    {
        Debug.WriteLine("Execute");
    }
}

重新运行,这是生成的 IL:

IL_0000:  newobj      UserQuery+Test..ctor
IL_0005:  stloc.0     // t
IL_0006:  ldloc.0     // t
IL_0007:  callvirt    UserQuery+Test.Execute

Test.Execute:
IL_0000:  ldstr       "Execute"
IL_0005:  call        System.Diagnostics.Debug.WriteLine
IL_000A:  ret         

Test..ctor:
IL_0000:  ldarg.0     
IL_0001:  ldsfld      System.String.Empty
IL_0006:  stfld       UserQuery+Test._Value
IL_000B:  ldarg.0     
IL_000C:  call        System.Object..ctor
IL_0011:  ret 

如您所见,初始化代码被“提升”到构造函数中,因此构造函数现在初始化该字段。

示例 3:将初始化移动到构造函数中

让我们将类更改为:

public class Test
{
    private string _Value;

    public Test()
    {
        _Value = string.Empty;
    }

    public void Execute()
    {
        Debug.WriteLine("Execute");
    }
}

现在是构造函数的 IL:

Test..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ldarg.0     
IL_0007:  ldsfld      System.String.Empty
IL_000C:  stfld       UserQuery+Test._Value
IL_0011:  ret 

现在这里的区别在于构造函数中代码的顺序,该字段是在调用基本构造函数之后初始化的,而在前面的示例中它是在之前初始化的。

结论

这些类型中可能没有构造函数,或者可能是那些反编译器不知道在其声明中初始化字段与在构造函数中初始化字段之间的区别。然而,我发现后者不太可能,所以我假设该类没有构造函数。

于 2013-10-09T11:35:50.870 回答
1

Telerik JustDecompile显示构造函数代码。

于 2013-10-09T11:30:12.400 回答