Fully instantiating an object through reflection without constructor

The closest answers I found related to this question didn't really do anything to help solve it, though perhaps I did a poor job searching for it.

Get a new object instance from a Type

Reflection instantiation

Instantiate an object with a runtime-determined type

Now, what I'm trying to solve is:

I want to fully and entirely fill out and initialize an object, where I only have the Type, and this object does not have a constructor, and I don't know what type it is until runtime.

private readonly Dictionary<string, object> exampleDict = new Dictionary<string, string> { { "String", "\"String\"" }, { "Guid", Guid.NewGuid() }, { "Boolean", False }, { "int", 0 }, { "Decimal", 5.004 }, { "Int32", 0 }, { "Float", 10.01 }, { "Double", 0.101 } };
//Essentially a dictionary of what to init properties to
private object PopulateType(Type propertyType)
{
    object o = Activator.CreateInstance(propertyType);
    if(exampleDict.hasKey(propertyType.ToString())) //If it is in the dictionary, init it
        o = exampleDict[propertyType.Name];
    else
        foreach(var property in o.getProperties())//Otherwise look at each of its properties and init them to init the object
            PopulateType(typeof(property));
}

The above isn't what I actually have and I doubt it'd work out of the box (the actual code currently has a slew of different things I tried from SO answers, and it was easier to just rewrite it how I wanted it)

I will also need to worry about arrays (and by extension lists and dictionaries) which'll act a bit differently, but I'm primarily trying to get the main part of the question down.

Thanks in advance for all the help - I'm just hoping this is possible :)

EDIT with more details: To put it another way, say I have the following classes:

public class ClassOne
{
    public string BirthCountry {get; set;}
    public string BirthCity {get; set;}
}
public class ClassTwo
{
    public string FirstName {get; set;}
    public string LastName {get; set;}
    public ClassOne BirthPlace {get; set;}
}

What I want to do is call:

object newObject = PopulateType(typeof(ClassOne))

OR

object newObject = PopulateType(typeof(ClassTwo))

I don't know in advance which one I'll use, and neither has a constructor. I want to be able to set BirthCountry and BirthCity to "String" if it is a ClassOne put into PopulateType, and I want to be able to set FirstName="String", LastName="String" and BirthPlace=new ClassOne { BirthCountry="String", BirthCity="String" } But I want to be able to do this for ANY class that I happen to have (these are just examples).

Edit further

I am able to make the base class from the type. But I haven't been able to hit the properties to set them to anything except null.

EDIT - With the help of Fruity Geek (many thanks friend) I was able to get the program working.

private object PopulateType(Type propertyType)
{
    object o = null;
    if (exampleDict.ContainsKey(propertyType.Name))
        o = exampleDict[propertyType.Name];
    else
    {
        var types = AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany(s => s.GetTypes()).Where(p => propertyType.IsAssignableFrom(p));
        try{o = Activator.CreateInstance(propertyType);}
        catch{o = Activator.CreateInstance(types.Last());}   
        foreach (PropertyInfo prop in o.GetType().GetProperties())
            try
            {
                prop.SetValue(o, PopulateType(prop.PropertyType), null);
            }
            catch (Exception){}
    }
    return o;
}

Note that the try/catch are to: Prevent exploding if the interface isn't implemented, and to not try to instance dicts/lists/arrays (those still need work)

Answers


You can use reflection to check if a property exists and set it.

PopulateType(Object obj)
{
    //A dictionary of values to set for found properties
    Dictionary<String, Object> defaultValues = new Dictionary<String, Object>();
    defaultValues.Add("BirthPlace", "Amercia");
    for (var defaultValue in defaultValues)
    {
        //Here is an example that just set BirthPlace to a known value Amercia
        PropertyInfo prop = obj.GetType().GetProperty(defaultValue.Key, BindingFlags.Public | BindingFlags.Instance);
        if(null != prop && prop.CanWrite)
        {
            prop.SetValue(obj, defaultValue.Value, null);
        }
    }
}

Need Your Help

Strange characters in HTML mails on iOS

ios wordpress utf-8 character-encoding phpmailer

I'm using phpMailer in a WordPress plugin to send HTML mails. This works very well. But unfortunataly some users have these strange characters on german Umlauts and the &amp;nbsp; for instance.

Creating/Using FileStream Thread Safe

multithreading delphi file-io race-condition delphi-6

In my Application when I write text files (logs, traces, etc), I use TFileStream class.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.