How to instantiate class without public constructor in C# during deserialization?

Of course, the problem as it is not difficult to resolve. We can use the reflection to do that and that’s all. But what will happen if we have such a class:

public sealed class User
{
    private readonly string _name;
    private readonly string _password;

    public User(string name, string password)
    {
        if (string.IsNullOrEmpty(name))
            throw new ArgumentNullException("name");

        if (string.IsNullOrEmpty(password))
            throw new ArgumentNullException("password");

        _name = name;
        _password = password;
    }

    public string Password
    {
        get { return _password; }
    }

    public string Name
    {
        get { return _name; }
    }
}

Then, you cannot simply use reflection without the knowledge about input parameters. Of course, if it cannot work with some default values like null or string.Empty then you could put some dummy information to every argument, and after that assign during the deserialization process you will assign the proper data to fields.

There is even simpler way to do that (and faster). You can use .NET Framework static method FormatterServices.GetUninitializedObject to do a work for you. This method is used e.g. in WCF default serializer to create an instance during deserialization.

The interesting thing is, what we have behind of this method:

[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
public static object GetUninitializedObject(Type type)
{
    if (type == null)
    {
        throw new ArgumentNullException("type");
    }
    if (!(type is RuntimeType))
    {
        throw new SerializationException(string.Format(CultureInfo.CurrentCulture,
                                Environment.GetResourceString("Serialization_InvalidType"), new object[] { type.ToString() }));
    }
    return nativeGetUninitializedObject((RuntimeType) type);
}

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern object nativeGetUninitializedObject(RuntimeType type);

So, what we have there is the native method to create the uninitialized object! But what exactly happens there? We could read a note about that:

// Gets a new instance of the object. The entire object is initialized to 0 and no
// constructors have been run. **THIS MEANS THAT THE OBJECT MAY NOT BE IN A STATE
// CONSISTENT WITH ITS INTERNAL REQUIREMENTS** This method should only be used for
// deserialization when the user intends to immediately populate all fields. This method
// will not create an unitialized string because it is non-sensical to create an empty
// instance of an immutable type.

But can we find what how code is looking like? Regarding discussion we can do that! Just follow instructions and you can see,  what exactly is there in C++ code which will create an empty object for us:)

Advertisements

One thought on “How to instantiate class without public constructor in C# during deserialization?

  1. Pingback: dotnetomaniak.pl

Leave a Reply

Fill in your details below or click an icon to log in:

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