所以我有一些代码可以在一个对象上设置一个属性。此代码来 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.
我怀疑它试图调用 BusinessObject
的 First
属性,而不是 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/