1

拡張メソッドがオブジェクトのプロパティを IDictionary にマップする最も効率的な方法は何ですか?

  • キーはプロパティ パスです (例: "Customer.Company.Address.Line1")
  • 値は、プロパティ値の文字列表現です (例: "123 Main St." または null またはデフォルト値の場合は "" (空の文字列))。
  • プロパティのコレクションにはまだパスしか含まれていません (例: public IList Invoices --> "Customer.Invoices" ですが、値はコレクション カウントです)

リフレクションの使用は最善のアプローチですか? 例はありますか?

ありがとうZ...

明確化の更新

  • ディクショナリ キーは、型階層ではなくプロパティ名に基づくパスである必要があります。そのため、Customer にプロパティがpublic Company ParentCompanyあり、Company にプロパティがあるpublic Address BillingAddress場合、キー パスは「ParentCompany.BillingAddress」である必要があります。
4

1 に答える 1

2

編集:

public static IDictionary<string, string> GetProperties<T>(this T obj)
    where T : class
{
    var properties = obj.GetPropertyList();
    return properties.ToDictionary(prop => prop.Item1, prop => prop.Item2);
}

public static IEnumerable<Tuple<string, string>> GetPropertyList<T>(this T obj)
    where T : class
{
    if (obj == null)
        throw new ArgumentNullException("obj");

    Type t = obj.GetType();

    return GetProperties(obj, t, t.Name);
}

private static IEnumerable<Tuple<string, string>> GetProperties(object obj, Type objType, string propertyPath)
{
    // If atomic property, return property value with path to property
    if (objType.IsValueType || objType.Equals(typeof(string)))
        return Enumerable.Repeat(Tuple.Create(propertyPath, obj.ToString()), 1);

    else
    {
        // Return empty value for null values
        if (obj == null)
            return Enumerable.Repeat(Tuple.Create(propertyPath, string.Empty), 1);

        else
        {
            // Recursively examine properties; add properties to property path
            return from prop in objType.GetProperties()
                   where prop.CanRead && !prop.GetIndexParameters().Any()
                   let propValue = prop.GetValue(obj, null)
                   let propType = prop.PropertyType
                   from nameValPair in GetProperties(propValue, propType, string.Format("{0}.{1}", propertyPath, prop.Name))
                   select nameValPair;
        }
    }
}

これでも、値パラメータのデフォルト値は処理されません。再帰的な反復をいつ停止するかについてのロジックが重要であることに注意してください。もともと私は値型のプロパティに立ち寄りましたが、それは文字列が他のオブジェクトのように扱われることを意味しました。そこで、文字列をアトミック型として扱うための特別なケースを追加しました。

于 2012-06-07T16:21:56.653 に答える