通过Expression设置嵌套属性

时间:2015-07-08 20:56:26

标签: c# properties lambda linq-expressions propertyinfo

我有以下对象:

public class ContactImport { 
    public long Id {get;set;}
    public Contact Contact {get;set;}
    public Company Company {get;set;}
    public Address Address {get;set;}
}

我希望能够根据传入(Expression<Func<T, dynamic>>)的表达式动态设置嵌套对象的属性。

为此,我有以下方法,这适用于在顶级对象(例如Id)上设置属性,但在尝试在嵌套对象上设置任何内容时失败(例如Contact.FirstName)

public static void SetPropertyValue<T, TProp>(this T target, Expression<Func<T, TProp>> member, TProp value) {
    var selectorExpr = (MemberExpression)(member.Body is UnaryExpression ? ((UnaryExpression)member.Body).Operand : member.Body);
    if (selectorExpr != null) {
        var property = selectorExpr.Member as PropertyInfo;
        if (property != null) {
            property.SetValue(target, value);
        }
     }
 }

看起来它试图在顶级对象上设置属性但不能。我认为这是可能的,但我不确定如何用我现在拥有的东西来实现它。

SetPropertyValue方法是这样调用的:

public class ImportCheck<T> {

    public int id { get; set; }
    public string Name { get; set; }
    public Type Type { get; set; }
    public bool Required { get; set; }
    public int? MinLength { get; set; }
    public int? MaxLength { get; set; }
    public string Value { get; set; }
    public Expression<Func<T, dynamic>> AssociatedProperty { get; set; }
}


    T pt = (T)Activator.CreateInstance(typeof(T));
    foreach (var m in mapping) {
        pt.SetPropertyValue(m.AssociatedProperty, Convert.ChangeType(m.Value, Nullable.GetUnderlyingType(m.Type) ?? m.Type));
    }

在上面的示例中,TContactImportm.AssociatedProperty为表达式,mappingList<ImportCheck<ContactImport>>

更新

我的问题似乎归结为这样一个事实:传递给SetPropertyValue的表达式的返回类型为dynamic。如果将其设置为int并且嵌套对象上的属性为int,那么一切正常。我遇到的问题是我需要显式设置表达式的结果以匹配目标属性的类型。然而,这给我留下了另一个问题,即我需要一个ImportCheck列表,每个Expression<Func<T,dynamic>>可能有不同的返回类型。

0 个答案:

没有答案