使用 lambda 表达式读取属性值

发布于 2024-07-26 06:18:20 字数 1125 浏览 3 评论 0原文

我正在为我的应用程序编写一个文件通用块,并开始使用 Lambda 表达式来管理块生成的规则集,以避免魔术字符串、配置地狱等的陷阱。

在我的映射类中,我有类似以下内容的行:

Map(x => x.Name).Length(20).PadLeft(true).PaddingChar("#");

This Works Fine这不是我的问题所在,我在 Map 方法中设置保存有关表达式的信息:

public override IPropertyMap Map(Expression<Func<T, object>> expression)
{
    var propertyMap = new FixedLengthPropertyMap
          {
              //Length = 20,
              //PaddingCharacter = " ",
              PadLeft = false,
              PropertyInfo = ReflectionHelper.GetProperty(expression)
          };

    _properties.Add(propertyMap);

    return propertyMap;
}

_properties 只是一个存储我的信息的 List我的问题是从属性中读取真实对象的数据的最佳方法是什么,目前我想出了与此类似的方法:

var map = new AgentMap();
var agent = new Agent {Name = "Bob"};

string output = map.Write(agent);

public override string Write<T>(T agent)
{
    var initial = _properties[0];
    return initial.PropertyInfo.GetValue(agent, null) as string;
}

有没有比使用 GetValue 方法更好的方法,因为早些时候我使用的是表达式树?

I'm writing a file generic block for my application and started with using Lambda expressions for managing my rule sets for block generation to avoid the pitfalls of magic strings, configuration hell etc.

Inside my mapping class I have lines similar to:

Map(x => x.Name).Length(20).PadLeft(true).PaddingChar("#");

This works fine and isn't where my question dwells, where I setup saving my information about the expression is in the Map method:

public override IPropertyMap Map(Expression<Func<T, object>> expression)
{
    var propertyMap = new FixedLengthPropertyMap
          {
              //Length = 20,
              //PaddingCharacter = " ",
              PadLeft = false,
              PropertyInfo = ReflectionHelper.GetProperty(expression)
          };

    _properties.Add(propertyMap);

    return propertyMap;
}

_properties is just a List<IPropertyMap> that stores my info where my question from what is the best way to have a real object's data be read from the properties currently I came up with something similar to this:

var map = new AgentMap();
var agent = new Agent {Name = "Bob"};

string output = map.Write(agent);

public override string Write<T>(T agent)
{
    var initial = _properties[0];
    return initial.PropertyInfo.GetValue(agent, null) as string;
}

Is there a better way than using the GetValue method since earlier on I'm using an expression tree?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

聆听风音 2024-08-02 06:18:20

我根本不明白为什么你真的需要使用表达式树。 只需让 Map 方法采用 Func 并将其存储:

public override IPropertyMap Map(Func<T, string> fetcher)
{
    var propertyMap = new FixedLengthPropertyMap
          {
              //Length = 20,
              //PaddingCharacter = " ",
              PadLeft = false,
              Delegate = fetcher // Delegate is of type Delegate
          };

    _properties.Add(propertyMap);

    return propertyMap;
}

那么:

public override string Write<T>(T agent)
{
    var initial = _properties[0];
    Func<T, string> fetcher = (Func<T, string>) initial.Delegate;
    return fetcher(agent);
}

您是否特别想了解该属性并使用表达式树?

I don't see why you really need to use expression trees at all. Just make the Map method take a Func<T, object> and store that:

public override IPropertyMap Map(Func<T, string> fetcher)
{
    var propertyMap = new FixedLengthPropertyMap
          {
              //Length = 20,
              //PaddingCharacter = " ",
              PadLeft = false,
              Delegate = fetcher // Delegate is of type Delegate
          };

    _properties.Add(propertyMap);

    return propertyMap;
}

Then:

public override string Write<T>(T agent)
{
    var initial = _properties[0];
    Func<T, string> fetcher = (Func<T, string>) initial.Delegate;
    return fetcher(agent);
}

Is there any reason you particularly wanted to know the property and use an expression tree?

不甘平庸 2024-08-02 06:18:20

在某种程度上,这取决于您的场景。 “简单”的答案是只编译表达式并调用它,但如果您在紧密循环中执行此操作,则会产生潜在的性能影响(传递委托会快得多)。

我不确定 if 是否适用于这种特定情况(因为代理),但为了避免进行过多的表达式编译,您可以寻找简单的场景和直接从表达式树中读取值; 一点 PropertyInfo/FieldInfo 会比编译它更快...

有关更多信息,请查看 TryEvaluate 此处,以及如何将其与Compile一起用作备份策略(尽管您具有已知委托类型的优势)。

In part, it depends on what your scenario is. The "simple" answer is to just compile the expression and invoke it, but that has a potential performance impact if you are doing it in a tight loop (passing a delegate would be a lot quicker).

I'm not sure whether if would apply in this particular case (because of the agent), but to avoid doing too much expression compilation, you can look for simple scenarios and read the value directly from the expression tree; a little bit of PropertyInfo/FieldInfo is going to be quicker than compiling it...

For more, look at TryEvaluate here, and how it is used with Compile as a backup strategy (although you have the advantage of a known delegate type).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文