通过反射完全实例化对象而无需构造函数

时间:2013-01-24 02:14:16

标签: c# reflection types initialization

我发现与这个问题相关的最接近的答案并没有真正做任何事情来帮助解决这个问题,但也许我找不到很好的工作。

Get a new object instance from a Type

Reflection instantiation

Instantiate an object with a runtime-determined type

现在,我想解决的是:

我想完全填写并初始化一个对象,其中我只有Type,而且这个对象没有构造函数,我不知道它在运行时是什么类型。

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));
}

以上不是我实际拥有的,我怀疑它是开箱即用的(实际代码目前有很多不同的东西,我尝试从SO答案,并且更容易重写它如何我想要它)

我还需要担心数组(以及扩展名列表和词典)会有所不同,但我主要是试图解决问题的主要部分。

提前感谢所有帮助 - 我只是希望这是可能的:)

有更多详情的编辑: 换句话说,我说有以下几个类:

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;}
}

我想做的是致电:

object newObject = PopulateType(typeof(ClassOne))

OR

object newObject = PopulateType(typeof(ClassTwo))

我事先并不知道我将使用哪一个,也没有构造函数。我希望能够将BirthCountryBirthCity设置为“字符串”,如果ClassOne放入PopulateType,我希望能够设置{{1} },FirstName="String"LastName="String" 但我希望能够为我碰巧拥有的任何课程做这件事(这些只是例子)。

进一步编辑

我能够从类型中创建基类。但我无法点击属性将它们设置为除null之外的任何内容。

编辑 - 在Fruity Geek的帮助下(非常感谢朋友)我能够让这个程序正常运作。

BirthPlace=new ClassOne { BirthCountry="String", BirthCity="String" }

请注意,try / catch是:如果未实现接口,则防止爆炸,并且不尝试实例dicts / lists / arrays(那些仍然需要工作)

1 个答案:

答案 0 :(得分:2)

您可以使用反射来检查属性是否存在并进行设置。

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);
        }
    }
}