2

この質問に関連して私が見つけた最も近い回答は、解決に役立つものではありませんでしたが、おそらく私はそれを検索するのが苦手でした.

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

また

object newObject = PopulateType(typeof(ClassTwo))

どちらを使用するかは事前にわかりませんし、どちらもコンストラクターを持っていません。に設定されている場合は「文字列」に設定できるようにしたいしBirthCountry、設定できるようにしたいが 、たまたま持っているすべてのクラスに対してこれを実行できるようにしたい(これらはちょうど例)。BirthCityClassOnePopulateTypeFirstName="String"LastName="String"BirthPlace=new ClassOne { BirthCountry="String", BirthCity="String" }

さらに編集

型から基本クラスを作成できます。しかし、プロパティをヒットしてnull以外に設定することはできませんでした。

編集 - Fruity Geek (感謝の友人) の助けを借りて、プログラムを動作させることができました。

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

インターフェイスが実装されていない場合は爆発を防ぎ、辞書/リスト/配列をインスタンス化しようとしません (これらにはまだ作業が必要です)。

4

1 に答える 1

4

リフレクションを使用して、プロパティが存在するかどうかを確認して設定できます。

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);
        }
    }
}
于 2013-01-24T03:14:58.433 に答える