Monday, April 21, 2008

Instantiating a Class Without Calling Its Constructor

Recently I came across a situation where I wanted to create an instance of a specific class without the constructor logic being executed. My first intuition was to look if reflection had any means to circumvent the constructor logic. Reflection offers a way to instantiate a class by calling its constructor regardless of the constructor's access modifier.

// Call the parameterless constructor of MyClass via reflection.
Type t = typeof(MyClass);
ConstructorInfo ci = t.GetConstructor(System.Type.EmptyTypes);
MyClass o = (MyClass)ci.Invoke(null);

Unfortunately reflection didn't help much in bypassing the constructor logic. Next I thought about the Activator class and its CreateInstance method which supposedly creates an instance of a class by calling the best matching constructor.

// Call the parameterless constructor of MyClass using Activator.
MyClass o = (MyClass)Activator.CreateInstance(typeof(MyClass));

If the class doesn't have a constructor CreateInstance throws an exception. In other words I wasn't getting any closer to a solution. I was starting to run out of ideas until I recalled that the SoapFormatter can deserialize a file into an object without calling the class's constructor. Only when the class implements ISerializable interface will the special constructor that takes SerializationInfo and StreamingContext as parameters be called. So, how exactly do SoapFormatter as well as BinaryFormatter create instances of classes without calling their constructors? The instances are created by using the static GetUninitializedObject from the FormatterServices class that contains a number of static helper methods for formatters.

// Create an instance of a class without calling its constructor.
MyClass o = (MyClass)FormatterServices.GetUninitializedObject(typeof(MyClass));

That's how easy it is. Of course this method should be used only when other methods for instantiating a class don't suit your needs as there probably is a minor performance hit associated with it.