如何使用Lambda表达式获取属性“path”和值?

5

我希望能够实现与ASP.NET MVC中的HtmlHelpers类似的功能。以下是示例:

@Html.EditorFor(model => model.SomeProperty.SomeInnerProperty)

HtmlHelper不仅可以获取SomeInnerProperty的值,还知道我所说的该属性的“路径”,因为它会创建带有属性的适当HTML元素:

name="SomeProperty.SomeInnerProperty"

我希望能够创建一个类似HtmlHelpers的方法,既可以获取值,又可以获取“路径”。我已经研究了现有的HtmlHelpers,但是这看起来很棘手。不过我已经成功创建了一种使用方法:

MyCustomMethod(model => model.SomeProperty.SomeInnerProperty);

private void MyCustomMethod(Expression<Func<object, object>> expression)
{
    // I can inspect the expression object in the debugger here
}

检查"expression"对象时,我可以通过反射来理解事情的内部情况,但我不确定我的解决方案有多健壮,因为我只是通过观察来理解事情。此外,这似乎比应该更困难;就像我错过了一些简单的东西。
有什么想法吗?
2个回答

2
为了获取完整路径: expression.Body.ToString()会给你 'model.SomeProperty.SomeInnerProperty'。获取第一个点之后的子字符串,得到 'SomeProperty.SomeInnerProperty'。
为了获取值: expression.Compile().Invoke(modelObject)

谢谢,@gp。我应该提到我已经看过expression.Body.ToString(),但是我觉得解析它有点不太好,而且也不确定能否依赖它。听起来我可以依赖它。我喜欢你的获取值的方法。 - Kirk Liemohn
Expression.ToString的实现使用ExpressionStringBuilder完成了相同的功能http://referencesource.microsoft.com/#System.Core/Microsoft/Scripting/Ast/Expression.cs#02b69d6c264d6a31。那么为什么不重用它而是编写自己的实现... - gp.

2
//basic
MemberExpression memberExpression = (MemberExpression) expression.Body;
string name = (memberExpression.Expression as MemberExpression).Member.Name;
name += "." + memberExpression.Member.Name;

//cycle
MemberExpression memberExpression = (MemberExpression) expression.Body;
string name = "";
while (memberExpression.Expression is MemberExpression)
{
    name = memberExpression.Member.Name + "." + name;
    memberExpression = (MemberExpression)memberExpression.Expression;
}

1
谢谢Alexandr。我应该提到这将是一些通用代码,我希望它不仅适用于model.SomeProperty.SomeInnerProperty,还适用于model.SomeProperty或model.SomeProperty.SomeInnerProperty.SomeInnerInnerProperty。你的解决方案部分是我通过观察发现的,但它有所帮助,因为我不知道我可以轻松地将事物强制转换为MemberExpression以检查属性而不是使用完整反射。我需要查找null或其他内容来确定要深入多少。 - Kirk Liemohn
我认为我更喜欢这个方法,而不是@ gp提到的expression.Body.ToString(),但他/她帮助了我如何获取值。我会看看是否有更多的回复,但迄今为止两个答案都可能值得一个绿色勾选标记。 - Kirk Liemohn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接