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.

Saturday, January 12, 2008

Static Members in Generic Classes

The other day I and Alessandro talked about how static members behave in generic classes. This might be blatantly obvious for most people but might cause some confusion for others. Imagine having a generic class of the following nature:

public class MyClass<T>
{
    private static string text = "uninitialized";

    public static string Text
    {
        get { return text; }
        set { text = value; }
    }
}

Now you're calling for example MyClass<string>.Text = "string"; — What do you think MyClass<int>.Text contains after this? Yup, it still contains the "uninitialized" string. This is due to the fact that at runtime native code is produced specifically for every type. In a sense you could think that there are two separate copies of the generic class, MyClass of string and MyClass of int which both have their own separate static members.

What if you actually wanted generic classes regardless of the type to share their static members? This is easily achieved by writing a separate static class and making the static members in the generic class act as wrappers for the members of the static class:

public class MyClass<T>
{
    public static string Text
    {
        get { return MyClassStatic.Text; }
        set { MyClassStatic.Text = value; }
    }
}

internal static class MyClassStatic
{
    private static string text = "uninitialized";

    public static string Text
    {
        get { return text; }
        set { text = value; }
    }
}

Now both MyClass<string>.Text and MyClass<int>.Text would refer to the same string.