相关疑难解决方法(0)

如何在C#表达式树中设置字段值?

鉴于:

FieldInfo field = <some valid string field on type T>;
ParameterExpression targetExp = Expression.Parameter(typeof(T), "target");
ParameterExpression valueExp = Expression.Parameter(typeof(string), "value");
Run Code Online (Sandbox Code Playgroud)

如何编译lambda表达式以将"target"参数上的字段设置为"value"?

c# lambda expression-trees

40
推荐指数
3
解决办法
2万
查看次数

创建属性setter委托

我创建了将属性lambda转换为委托的方法:

public static Delegate MakeGetter<T>(Expression<Func<T>> propertyLambda)
{
    var result = Expression.Lambda(propertyLambda.Body).Compile();
    return result;
}

public static Delegate MakeSetter<T>(Expression<Action<T>> propertyLambda)
{
    var result = Expression.Lambda(propertyLambda.Body).Compile();
    return result;
}
Run Code Online (Sandbox Code Playgroud)

这些工作:

Delegate getter = MakeGetter(() => SomeClass.SomeProperty);
object o = getter.DynamicInvoke();

Delegate getter = MakeGetter(() => someObject.SomeProperty);
object o = getter.DynamicInvoke();
Run Code Online (Sandbox Code Playgroud)

但这些不会编译:

Delegate setter = MakeSetter(() => SomeClass.SomeProperty);
setter.DynamicInvoke(new object[]{propValue});

Delegate setter = MakeSetter(() => someObject.SomeProperty);
setter.DynamicInvoke(new object[]{propValue});
Run Code Online (Sandbox Code Playgroud)

MakeSetter行失败,"无法根据用法推断出类型参数.请尝试明确指定类型参数."

我正在尝试做什么?提前致谢.

c# lambda delegates properties

36
推荐指数
3
解决办法
2万
查看次数

反射性能 - 创建代理(属性C#)

我在使用反射时遇到了性能问题.
所以我决定为我的对象的属性创建委托,到目前为止得到了这个:

TestClass cwp = new TestClass();
var propertyInt = typeof(TestClass).GetProperties().Single(obj => obj.Name == "AnyValue");
var access = BuildGetAccessor(propertyInt.GetGetMethod());
var result = access(cwp);
Run Code Online (Sandbox Code Playgroud)
static Func<object, object> BuildGetAccessor(MethodInfo method)
{
    var obj = Expression.Parameter(typeof(object), "o");

    Expression<Func<object, object>> expr =
        Expression.Lambda<Func<object, object>>(
            Expression.Convert(
                Expression.Call(
                    Expression.Convert(obj, method.DeclaringType),
                    method),
                typeof(object)),
            obj);

    return expr.Compile();
}
Run Code Online (Sandbox Code Playgroud)

结果非常令人满意,比使用传统方法快30-40倍(PropertyInfo.GetValue (obj, null);)

问题是:我怎样才能创建SetValue一个属性相同的属性?不幸的是没有办法.

我这样做是因为我不能使用方法,<T>因为我的应用程序的结构.

c# reflection expression action setvalue

25
推荐指数
2
解决办法
1万
查看次数

.NET 3.5表达式树中的赋值

是否可以将赋值编码到表达式树中?

linq expression-trees

12
推荐指数
3
解决办法
6992
查看次数

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

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

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

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

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

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

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

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

当此代码运行时,我们收到错误:

对象与目标类型不匹配.

我怀疑它试图打电话FirstBusinessObject,而不是NameInfo.如何修改我的代码来处理这个'嵌套'的情况?

.net c# reflection expression-trees

8
推荐指数
2
解决办法
2147
查看次数