c# - 创建一个 Action<T> 到 "set"属性,当我为 "get"提供 LINQ 表达式时

标签 c# expression-trees

我希望能够生成编译表达式来设置属性,给定为属性提供“get”方法的 lambda 表达式。

这是我正在寻找的:

public Action<int> CreateSetter<T>(Expression<Func<T, int>> getter)
{
    // returns a compiled action using the details of the getter expression tree, or null
    // if the write property is not defined.
}

我仍在努力理解各种类型的 Expression 类,因此,如果您能为我指明正确的方向,那就太好了。

最佳答案

以@Ani 的回答为起点,您可以使用以下内容生成编译表达式

[TestMethod]
public void CreateSetterFromGetter()
{
    Action<Person, int> ageSetter = InitializeSet((Person p) => p.Age);
    Action<Person, string> nameSetter = InitializeSet((Person p) => p.Name);

    Person p1 = new Person();
    ageSetter(p1, 29);
    nameSetter(p1, "John");

    Assert.IsTrue(p1.Name == "John");
    Assert.IsTrue(p1.Age == 29);
}

public class Person { public int Age { get; set; } public string Name { get; set; } }

public static Action<TContainer, TProperty> InitializeSet<TContainer, TProperty>(Expression<Func<TContainer, TProperty>> getter)
{
    PropertyInfo propertyInfo = (getter.Body as MemberExpression).Member as PropertyInfo;

    ParameterExpression instance = Expression.Parameter(typeof(TContainer), "instance");
    ParameterExpression parameter = Expression.Parameter(typeof(TProperty), "param");

    return Expression.Lambda<Action<TContainer, TProperty>>(
        Expression.Call(instance, propertyInfo.GetSetMethod(), parameter),
        new ParameterExpression[] { instance, parameter }).Compile();
}

您应该缓存编译后的表达式,以便多次使用。

关于c# - 创建一个 Action<T> 到 "set"属性,当我为 "get"提供 LINQ 表达式时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4596453/

相关文章:

c# - 解析表达式(带有自定义函数和操作)

c# - 如何从 C# 中的二维数组中删除一行?

.net - "this"的启发式和闭包好吗? (表达式树)

c# - 通过表达式调用可枚举平均值

c# - 我可以停止 .NET 4 执行尾调用消除吗?

c# - 将返回表达式的方法引用到另一个方法的语法?

.net - 转换和拆箱有什么区别?

c# - 如何使用 LINQ 按多个项目订购?

c# - Windows Phone 8.1/Windows 8.1如何设置http客户端请求操作超时

c# - 如何将 .aspx 响应定向到 Controller 方法中