RSS

Reflection: Call private Constructor with optional parameters

16 Apr

If you want to create a test for a class that has only a private constructor and that has some optional parameters you might result in nasty reflection problems. As you know private constructors can be easily called via reflection:

public class Test
{
    public static readonly Test Field1 = new Test("Value1");
    public static readonly Test Field2 = new Test("Value2", true);

    public Test(string value, bool isActive = false)
    {
        // [...]
    }
    // [...]
}


var ctor = typeof(Test).GetConstructor(
    BindingFlags.NonPublic |
    BindingFlags.Instance,
    null,
    new[] { typeof(string), typeof(bool)},
    null);

This code will not resolve the correct constructor and returns null, even though you pass only new[] { typeof(string)} as parameter for the type array. There is a simple binding flag that has additionally set: BindingFlags.OptionalParamBinding

By adding this enumeration value to the bindingAttr-parameter you have the working code:

var ctor = typeof(Test).GetConstructor(
    BindingFlags.NonPublic |
    BindingFlags.Instance |
    BindingFlags.OptionalParamBinding,
    null,
    new[] { typeof(string), typeof(bool)},
    null);

Just do not forget that if you do not pass a value for isActive you have to pass Type.Missing when you call the Invoke method. If you do not add the second parameter, even though it is optional, a TargetParameterCountException will be thrown.

var instance = ctor.Invoke(new[] { "Test", Type.Missing });

Edit

If you are using .NET 4.5 or newer you can also shorten the above code by creating an instance using GetTypeInfo with following code.

var instance = typeof(Test).GetTypeInfo()
                           .DeclaredConstructors
                           .First(i => i.IsPrivate)
                           .Invoke(new[]
                           {
                               "Test",
                               Type.Missing,
                               Type.Missing
                           });
Advertisements
 
Leave a comment

Posted by on April 16, 2015 in C-Sharp

 

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: