Question

In .net decomplilers, i'm not able to see the code for constructors. I've tested in many .net decompilers but none of them are showing constructor code. Is there any decomplier which shows that code.

Thanks in advance enter image description here

Was it helpful?

Solution

All .NET types defined by C# (I don't know how VB.NET or other languages do this, they might do the same, they might not) will have a constructor.

If you don't explicitly add a constructor, one will be provided for you by the compiler.

I've tested (earlier) the Telerik decompiler, Reflector, and dotPeek by JetBrains, and they all show constructor code when there is code to show.

Here's dotPeek 1.1 showing the constructor of Tuple<T1, T2>:

constructor decompiled by dotPeek 1.1">

However, the decompiler might opt to remove the constructor because it cannot see your original source code, so instead it tries to infer what kind of code would generate the IL you gave it. It is thus likely that even if your code explicitly writes out an empty constructor, it is compiled 100% identical to what the compiler would provide for you without it, and the decompiler thus assumes you didn't write out an empty constructor.

TL;DR: Judging by the documentation of the MultipleLookupField constructor, it has no parameters. It is thus possible that its only purpose is to call the base constructor and nothing else. As such, it may be completely unnecessary to decompile since a likely case was that one was not written out in the source code either.

However, to show that all classes have constructors, let's look at some examples.

The following examples can be tested in LINQPad by executing the code and then clicking the IL button above the results to see the decompiled IL. The decompiler of LINQPad (mono.cecil I belive) does not do this kind of inference to the same level so it will show the constructors.

Example 1: No constructor or code that would be placed in the constructor

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

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

Generated 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     

As you can see, there is a constructor in there, but all it does is call the base constructor from System.Object.

Example 2: Adding a string field with a default value

Now let's do something else, add this field to the class:

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

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

Re-run and here's the generated 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 

As you can see, the initialization code was "lifted" into the constructor, thus the constructor now initializes the field.

Example 3: Moving the initialization into the constructor

Let's change the class to this:

public class Test
{
    private string _Value;

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

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

Here's the IL of the constructor now:

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 

The difference here now is the ordering of the code in the constructor, the field is initialized after the base constructor was called, whereas it was initialized before in the previous example.

Conclusion

There might be no constructor in those types, or it might be that those decompilers doesn't know the difference between initializing the fields in their declarations vs. in the constructor. I find the latter unlikely however, so I would assume that the class has no constructor.

OTHER TIPS

Telerik JustDecompile shows constructor code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top