Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this does not create a default constructor?

Tags:

c#

constructor

I am wondering why this throws an exception (at execution time):

IAgentIndicator iai = (IAgentIndicator)Activator.CreateInstance(agentIndicatorType);

When I have a constructor with default parameters (but when I don't create the constructor public foo() :

public class foo : IAgentIndicator
{
    public foo(int a = 0, int b = 0)
    {
    }
}

Is not the parameterless constructor generated at compile-time ?

like image 882
RUser4512 Avatar asked Dec 03 '22 15:12

RUser4512


2 Answers

There are two issues here:

  1. A parameterless constructor is generated automatically for you only if you don't define any constructors yourself. Clearly this is not the case here, since you've manually declared a constructor.

  2. Optional parameters are little more than compile-time syntactic sugar at the call spot. A parameterized constructor does not count as a parameterless one, even if all of its parameters are optional.

like image 70
Theodoros Chatzigiannakis Avatar answered Dec 14 '22 21:12

Theodoros Chatzigiannakis


Is not the parameterless constructor generated at compile-time ?

As others said, a default constructor will only be generated if you haven't provided a constructor implementation yourself which takes arguments.

From the specification (§10.10.4)(emphasis mine):

If a class contains no instance constructor declarations, a default instance constructor is automatically provided. That default constructor simply invokes the parameterless constructor of the direct base class. If the direct base class does not have an accessible parameterless instance constructor, a compile-time error occurs.

If you look at the signature for your type in IL, you'll see that it creates a constructor with two parameters which are annotated with an [opt] tag and have default values:

.method public hidebysig specialname rtspecialname 
instance void .ctor (
    [opt] int32 a,
    [opt] int32 b
) cil managed 
{
    .param [1] = int32(0)
    .param [2] = int32(0)
    // Method begins at RVA 0x207c
    // Code size 9 (0x9)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: call instance void [mscorlib]System.Object::.ctor()
    IL_0006: nop
    IL_0007: nop
    IL_0008: ret
} // end of method foo::.ctor

This is not an empty constructor as Activate.CreateInstance expects.

like image 44
Yuval Itzchakov Avatar answered Dec 14 '22 22:12

Yuval Itzchakov