我不能在.net反射器/其他反编译器中看到构造函数的代码

时间:2013-10-09 10:55:13

标签: c# .net decompiling decompiler

在.net decomplilers中,我无法看到构造函数的代码。我已在许多.net反编译器中测试过,但它们都没有显示构造函数代码。是否有任何可以显示代码的装饰。

提前致谢 enter image description here

2 个答案:

答案 0 :(得分:4)

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

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

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

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

Tuple<T1, T2> constructor decompiled by dotPeek 1.1

然而,反编译器可能会选择删除构造函数,因为它无法看到您的原始源代码,因此它会尝试推断哪种代码会生成您提供的IL。因此,即使你的代码明确地写出一个空的构造函数,它也可能与编译器在没有它的情况下为你提供的编译100%完全相同,因此反编译程序假设你没有写出一个空构造函数。

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

但是,为了表明所有类都有构造函数,让我们看一些例子。

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

示例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 

现在的区别在于构造函数中代码的排序,在调用基础构造函数之后初始化字段,而在之前的中初始化示例

结论

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

答案 1 :(得分:1)

Telerik JustDecompile显示构造函数代码。