[c#] Instantiating an object with a private constructor

Not too long ago, I needed to modify a type available in the the BCL which didn’t have a public constructor or any method for creating an instance of the object. The solution was to use reflection to invoke the type’s private constructor.

Caveat!
Most times, these types are designed with private methods for a reason. There may be internal dependencies which can cause all kinds of problems if they’re not met. Only do something like this if you’re writing tests against the constructor or exploring the capabilities of Reflection.

The ConstructorInfo Class is the one we’ll use. If your constructor is parameterless and non-public, you can instead do:

var myType = (MyType)Activator.CreateInstance(typeof(MyType), true /*nonPublic*/);

To instantiate an object from a non-public constructor with parameters, you’ll need three things:

  • the target type
  • an array of parameter types (same order as signature)
  • a reference to the constructor

Suppose your target type is defined as:

  class Example
    {
        public string Display { get; private set; }
        private Example(string msg)
        {
            Display = msg;
        }
    }

To instantiate this object, you can do the following:

      // 1. the target type
      var exampleType = typeof(Example);

      // 2. an array of parameter types (same order as signature)
      var argTypes = new Type[] { typeof(string) };

      // 3. a reference to the constructor
      // Because method signatures must be unique in parameters and return type,
      // this will return the matching constructor, or ctor will be null.
      ConstructorInfo ctor = exampleType.GetConstructor(
          BindingFlags.Instance | BindingFlags.NonPublic,
          null, argTypes, null);

      // similar to var example = new Example("You've set me privately!")
      var example = (Example)ctor.Invoke(new []{ "You've set me privately!" });

      Console.WriteLine("Example's display: {0}", example.Display);

Note:
ConstructorInfo requires FullTrust.

Flattr this!