0

問題

ExpandoObjectC# を使用して、 fromにキャストされたオブジェクトをトラバースし、XMLすべての "price" プロパティを新しい値に置き換える必要があります。

このオブジェクトは非常に構造化されておらず、ネストされたノード (実際にはネストされた ExpandoObjects) のレイヤーが多数あります。より具体的には、階層は次のようになります。

商品 => 価格、数量、付属品

各アクセサリには価格と数量があり、それ自体にアクセサリがある場合があります。これが再帰が必要な理由です。

私がこれまでに持っているもの

  public ExpandoObject UpdatePricing(ExpandoObject exp)
    {
        //Is there a price property?
        var hasPrice = exp.Any(a => a.Key == "price");
        if (hasPrice)
        {
            //update price here
            exp.price = 0; //Some other price
        }

        //Now loop through the whole object.  If any of the properties contain an expando, then call this method again
        foreach (var kvp in exp)
        {
            if (kvp.Value is ExpandoObject)
            {
                //THIS CODE IS NO GOOD BECAUSE kvp.Value has no setter!!
                kvp.Value = UpdatePricing(kvp.Value);
            }
        }

        return exp;
    }

私が遭遇する問題はkvp.Value、セッターがないため、このメソッドを再帰的に実行できないことです。

任意の提案をいただければ幸いです。ありがとう!

4

3 に答える 3

2

ExpandoObject についてはよくわかりません。しかし、ほとんどのディクショナリの実装と同様に、キーと値のペアを更新して別の値を持たせたい場合は、ディクショナリ インターフェイスを経由する必要があると一般的に想定しています。

コンテンツを列挙している間は、(おそらく) 辞書を変更できないことに注意してください。そのため、更新する要素のリストを作成し、それを別の操作で行う必要があります。

例えば:

List<string> keysToUpdate = new List<string>();

foreach (var kvp in exp)
{
    if (kvp.Value is ExpandoObject)
    {
        keysToUpdate.Add(kvp.Key);
    }
}

foreach (string key in keysToUpdate)
{
    exp[key] = UpdatePricing(exp[key]);
}

値の 2 回目の取得を避けるために、KeyValuePair 値全体をリストに保持することもできますが、ここでは重要な最適化ではないと思います。

于 2014-10-17T23:31:23.040 に答える
2

ExpandoObject実装されているためIDictionary<string, Object>、物事は少し簡単になります。void結果を再割り当てする必要がないため、戻り値の型を に変更することもできます。

void UpdatePrice(ExpandoObject expando, decimal price)
{
    var map = (IDictionary<string, Object>)expando;
    if (map.ContainsKey("price"))
        map["price"] = price;
    foreach (var value in map.Values) 
    {
        if (value is ExpandoObject)
            UpdatePrice((ExpandoObject)value, price);
    }
}
于 2014-10-17T23:42:00.703 に答える