views:

7920

answers:

5

Take the following class as an example:

class Sometype
{
    int someValue;

    public Sometype(int someValue)
    {
        this.someValue = someValue;
    }
}

I then want to create an instance of this type using reflection:

Type t = typeof(Sometype);
object o = Activator.CreateInstance(t);

Normally this will work, however because SomeType has defined a non-parameterless constructor, the call to Activator.CreateInstance will throw an exception of type MissingMethodException with the message "No parameterless constructor defined for this object." Is there an alternative way to still create an instance of this type? It'd be kinda sucky to add parameterless constructors to all my classes.

+5  A: 

I originally posted this answer here, but here is a reprint since this isn't the exact same question but has the same answer:

FormatterServices.GetUninitializedObject() will create an instance without calling a constructor. I found this class by using Reflector and digging through some of the core .Net serialization classes.

I tested it using the sample code below and it looks like it works great:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;

namespace NoConstructorThingy
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = (MyClass)FormatterServices.GetUninitializedObject(typeof(MyClass)); //does not call ctor
            myClass.One = 1;
            Console.WriteLine(myClass.One); //write "1"
            Console.ReadKey();
        }
    }

    public class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("MyClass ctor called.");
        }

        public int One
        {
            get;
            set;
        }
    }
}
Jason Jackson
Awesome, looks like that's exactly what I need. I assume uninitialized means all its memory will be set to zeros? (Similar to how structs are instantiated)
Aistina
Whatever the default value is for each type will be the default. So objects will be null, ints 0, etc. I do think that any class-level initialization occurs, but no constructor is run.
Jason Jackson
+13  A: 

Use this overload of the CreateInstance method:

public static Object CreateInstance(
    Type type,
    params Object[] args
)

Creates an instance of the specified type using the constructor that best matches the specified parameters.

See: http://msdn.microsoft.com/en-us/library/wcxyzt4d.aspx

iik
Thanks that worked great and very clean and simple
Jon
A: 

couldn't you simply use default(T) ?

Tracker1
That returns null for classes.
Aistina
+1  A: 

Good answers but unusable on the dot net compact framework. Here is a solution that will work on CF.Net...

class Test
{
    int _myInt;

    public Test(int myInt)
    {
        _myInt = myInt;
    }

    public override string ToString()
    {
        return "My int = " + _myInt.ToString();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var ctor = typeof(Test).GetConstructor(new Type[] { typeof(int) });
        var obj = ctor.Invoke(new object[] { 10 });
        Console.WriteLine(obj);
    }
}
SDX2000
This is the way I'd call a non-default constructor. I'm not sure I'd ever want to create an object without calling any constructor at all.
Rory MacLeod
You may want to create an object without calling constructors if you are writing custom serializers.
SDX2000
@SDX2000 Yup, that's the exact use case scenario this question was for :)
Aistina
+2  A: 

FormatterServices.GetUninitializedObject not allow to create uninitialized string. You may get exception: System.ArgumentException: Uninitialized Strings cannot be created.

Please keep this in mind.

Bartosz Pierzchlewicz

Bartosz Pierzchlewicz
Thanks for the heads up, but I'm already handling strings and basic types separately.
Aistina