【问题标题】:Get value of nested property passed through a lambda expression获取通过 lambda 表达式传递的嵌套属性的值
【发布时间】:2014-11-17 18:51:53
【问题描述】:

我正在尝试为一个类构建一个字符串,其中包含该实例的所有属性名称及其各自值的列表。

根据问题Get Property Info from an object without giving the property name as string,我使用Expression 类型Func 类型T, Object 来获取属性名称,如下所示:

Private Function GetPropertyValuePair(Of T)(lambda As Expression(Of Func(Of T, Object))) As String
    Dim body As Expression = lambda

    'ensure we have the right type of thing
    If TypeOf body Is LambdaExpression Then body = DirectCast(body, LambdaExpression).Body
    If TypeOf body Is UnaryExpression Then body = DirectCast(body, UnaryExpression).Operand
    If body.NodeType <> ExpressionType.MemberAccess Then Throw New InvalidOperationException()

    'get property info
    Dim memberInfo = DirectCast(body, MemberExpression).Member
    Dim propInfo = DirectCast(memberInfo, PropertyInfo)

    Return propInfo.Name + " - " + propInfo.GetValue(Me, Nothing)
End Function

通过这种方式,我通过获取PropertyInfo 获取当前值,并使用GetValue 在当前实例中搜索该属性。

那我可以这样称呼它:

GetPropertyValuePair(Of Foo)(Function(x) x.Bar)

这将产生:

Bar - WhateverTheValueIsForBar

问题是当我的属性是嵌套时,GetValue 会抛出异常:

对象与目标类型不匹配。

例如,在运行以下表达式时:

GetPropertyValuePair(Of Foo)(Function(x) x.Bar.Car)

属性信息的类型为Car,在Foo 上无法直接找到。

我可以从原始 lambda 表达式中获取实例值,而不必首先使用 GetValue 进行搜索吗?

这可以通过 MVC @Html.EditorFor 帮助器实现,因此必须有某种机制来传递传入函数的值,如下所示:

@Html.EditorFor(Function(model) model.Bar.Car)

有什么想法吗?

【问题讨论】:

    标签: .net vb.net reflection lambda propertyinfo


    【解决方案1】:

    我根据How to evaluate a lambda expression拼凑了一个解决方案。

    您可以Compile 表达式在其中生成可运行函数。

    Dim func = lambda.Compile()
    Dim output = func(Me)
    

    由于我仍在使用 lambdas,所以这里有一点解释:

    在表达式中,我们将函数签名声明为如下所示Func(Of T, Object)
    当我们调用该方法时,我们告诉函数评估的行为是这样的x =&gt; x.Bar.Car

    编译将为我们提供一个新函数,存储为局部变量,其行为如下:

    Function Anonymous(x as T) As Object
        Return x.Bar.Car
    End
    

    所以我们实际上根本没有传入实例。我们刚刚传入了调用这个匿名函数并传入 T 类型的东西时会发生什么的定义。

    所以我们仍然需要拉入Me。在这种情况下,因为这个函数恰好位于同一个类中,所以我们有点作弊,因为该方法已经可以访问实例变量。如果它在其他地方被抽象出来,则必须将实例本身作为附加参数传入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多