gpt4 book ai didi

c# - 如何从字符串中为深层属性创建表达式树/lambda

转载 作者:可可西里 更新时间:2023-11-01 08:41:50 26 4
gpt4 key购买 nike

给定一个字符串:“Person.Address.Postcode” 我希望能够在 Person 的实例上获取/设置此邮政编码属性。我怎样才能做到这一点?我的想法是用“。”分割字符串。然后遍历各个部分,寻找前一个类型的属性,然后构建一个看起来像这样的表达式树(对伪语法表示歉意):

(person => person.Address) address => address.Postcode

不过,我在创建表达式树时遇到了真正的麻烦!如果这是最好的方法,有人可以建议如何去做,还是有更简单的替代方法?

谢谢

安德鲁

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

public Person()
{
Address = new Address();
}
}

public class Address
{
public string Postcode { get; set; }
}

最佳答案

这听起来像是您使用正则反射进行排序,但对于信息,为嵌套属性构建表达式的代码与 this order-by code 非常相似.

请注意,要设置一个值,您需要在属性上使用 GetSetMethod() 并调用它 - 构造后没有用于赋值的内置表达式(尽管它是 supported in 4.0 )。

(编辑)像这样:

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
class Foo
{
public Foo() { Bar = new Bar(); }
public Bar Bar { get; private set; }
}
class Bar
{
public string Name {get;set;}
}
static class Program
{
static void Main()
{
Foo foo = new Foo();
var setValue = BuildSet<Foo, string>("Bar.Name");
var getValue = BuildGet<Foo, string>("Bar.Name");
setValue(foo, "abc");
Console.WriteLine(getValue(foo));
}
static Action<T, TValue> BuildSet<T, TValue>(string property)
{
string[] props = property.Split('.');
Type type = typeof(T);
ParameterExpression arg = Expression.Parameter(type, "x");
ParameterExpression valArg = Expression.Parameter(typeof(TValue), "val");
Expression expr = arg;
foreach (string prop in props.Take(props.Length - 1))
{
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
// final property set...
PropertyInfo finalProp = type.GetProperty(props.Last());
MethodInfo setter = finalProp.GetSetMethod();
expr = Expression.Call(expr, setter, valArg);
return Expression.Lambda<Action<T, TValue>>(expr, arg, valArg).Compile();

}
static Func<T,TValue> BuildGet<T, TValue>(string property)
{
string[] props = property.Split('.');
Type type = typeof(T);
ParameterExpression arg = Expression.Parameter(type, "x");
Expression expr = arg;
foreach (string prop in props)
{
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
return Expression.Lambda<Func<T, TValue>>(expr, arg).Compile();
}
}

关于c# - 如何从字符串中为深层属性创建表达式树/lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/536932/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com