views:

135

answers:

3

The class to instantiate:

public class InstantiateMe
{
    public String foo
    {
        get;
        set;
    }
}

Some pseudo-code:

public void CreateInstanceOf(Type t)
{
    var instance = new t();

    instance.foo = "bar";
}

So far I'm figuring that I need to use reflection to get this done, given the dynamic nature of what I want to achieve.

Here's my success criteria's:

  • Create an instance of any type
  • Create instances of types without having to invoke their constructor
  • Access all public properties

I would greatly appreciate some working example-code. I'm not new to C#, but I've never worked with reflection before.

+3  A: 

Try the following to actually create the instance.

Object t = Activator.CreateInstance(t);

It is not possible however, without generics and constraints to statically access the members as shown in your example.

You could do it with the following though

public void CreateInstanceOf<T>() where T : InstantiateMe, new()
{
    T i = new T();
    i.foo = "bar";
}
JaredPar
That would be: T obj = Activator.CreateInstance<T>(); ;-)
Wim Hollebrandse
It should be T ins = Activator.CreateInstance<T>();
Gonzalo
@Wim, Gonzalo, thanks. Fixed it to use the non-generic CreateInstance method.
JaredPar
Nice solution, though it seems to defeat the object of using generics, to then restrict it to a single type.
Wim Hollebrandse
+4  A: 

You'd basically need to use Reflection. Use Activator.CreateInstance() to construct your type and then call InvokeMember() on the type, to set the property:

public void CreateInstanceOfType(Type t)
{
    var instance = Activator.CreateInstance(t); // create instance

    // set property on the instance
    t.InvokeMember(
        "foo", // property name
        BindingFlags.SetProperty,
        null,
        obj,
        new Object[] { "bar" } // property value
    );
}

To access all the properties of the generic type and set/get them, you can use GetProperties() which returns a PropertyInfo collection, which you can iterate through:

foreach (PropertyInfo property in type.GetProperties())
{ 
    property.GetValue() // get property
    property.SetValue() // set property
}

Also, see the documentation for more ways of using InvokeMember().

Wim Hollebrandse
Docs and Intellisense are doing nothing for me at. Could you provide me with some working code?
roosteronacid
Edited accordingly.
Wim Hollebrandse
@Wim: `Activator.CreateInstance(T)` is not working when I try to instantiate a parameter-less class. Any ideas?
roosteronacid
Activator.CreateInstance(typeof(T)) - or simply T obj = new T();
Wim Hollebrandse
@Wim: It seems like your code is ignoring the SetProperty binding flag. I get a System.MissingMethodException
roosteronacid
OK - I finally tested it, rather than typing into a HTML textbox. ;-)
Wim Hollebrandse
@Wib: Now you broke the dynamic nature of your example--I want the method to be able to instantiate and use properties on _any_ type. Not just a pre-defined one. It should not return anything, just create an instance of a type passed as a parameter: `CreateInstanceOf(Type t) { /* new up type (t). Do stuff with the instance */ }`
roosteronacid
Well, adjust it accordingly, and don't return the type.
Wim Hollebrandse
Modified it to add another snippet which goes through all the properties of the type.
Wim Hollebrandse
Thanks a bunch Wim. I've edited your answer to better fit the question. Hope you don't mind.
roosteronacid
Sure, no probs mate.
Wim Hollebrandse
A: 

Since you have the type you want to instantiate, you can use a generic helper method for that:

public static T New() where T : new()
{
    return new T();
}

Else if you are pulling out the type of some where else (like a dynamically loaded assembly) and you have not access to the type directly (it is some sort of meta programming or reflected data) you should use reflection.

Kaveh Shahbazian