c# - 如何使用 Expression<Func> 设置嵌套属性?

标签 c# .net reflection expression-trees

所以我有一些代码可以在一个对象上设置一个属性。此代码来 self 们在单元测试中使用的内部验证类。所以代码可能会提供类似

private static void SetDeepValue(object targetObject, Expression<Func<string>> propertyToSet, object valueToSet)
        {
            var underlyingProperty = ((PropertyInfo)((MemberExpression)propertyToSet.Body).Member);
            underlyingProperty.SetValue(targetObject, valueToSet);
        }

此代码在单元测试类型环境中使用,然后我们可以在其中进行调用

foreach (string currentTestCaseValue in TestCaseSets)
{
     BusinessObject myCustomer = new BusinessObject();
     SetDeepValue(myCustomer, ()=>myCustomer.FirstName,currentTestCaseValue);
     ValidateBusinessRules(myCustomer);
}

(为简洁/复杂而简化的代码)

然而,现在,由于一些重构,我们留下了类似的东西:

foreach (string currentTestCaseValue in TestCaseSets)
    {
         BusinessObject myCustomer = new BusinessObject();
         SetDeepValue(myCustomer, ()=>myCustomer.NameInfo.First,currentTestCaseValue);
         ValidateBusinessRules(myCustomer);
    }

当这段代码运行时,我们得到错误:

Object does not match target type.

我怀疑它试图调用 BusinessObjectFirst 属性,而不是 NameInfo。我如何修改我的代码来处理这种“嵌套”情况?

最佳答案

以下是通常将字符串 "ColumnName1.ColumnName2" 转换为 lambda 表达式 x => x.ColumnName1.ColumnName2 的方式:

Expression<Func<T, object>> ForNestedProperty(string columnName)
{
    // x
    ParameterExpression param = Expression.Parameter(typeof(T), "x");

    // x.ColumnName1.ColumnName2
    Expression property = columnName.Split('.')
                                    .Aggregate<string, Expression>
                                    (param, (c, m) => Expression.Property(c, m));

    // x => x.ColumnName1.ColumnName2
    Expression<Func<T, object>> lambda = Expression.Lambda<Func<T, object>>(
        Expression.Convert(property, typeof(object)), param);
    return lambda;
}

(复制自here)

关于c# - 如何使用 Expression<Func> 设置嵌套属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29084894/

相关文章:

c# - OpenIddict 问题

C# CA2000 在失去作用域之前处理对象

c# - 我如何找到从 C# 类方法调用的方法 - 而不是在运行时

Go - 如何更改指针参数的值?

c# - C# 中是否有任何压缩和加密库?

c# - 如何在运行时重建 Windows 应用程序

c# - 为什么我在 Windows 7 而不是 XP 上使用套接字接收 UDP 广播时看到重复的数据包?

.net - 如何使用 C# 从指定的上下文菜单中获取父控件?

.net - ExtJS 4 : Saving record in record edit form to server and update grid store

visual-studio - 如何基于另一个类生成代码?