Expression.PropertyOrField 中的不一致行为

Inconsistent behavior in Expression.PropertyOrField

第一个表达式通过,但第二个没有..错误是

AmbigiouseMatchExeption

有人知道为什么 class 的字段和 属性 的行为不一致吗? 如何解决?

Expression.PropertyOrField 方法使用 GetProperty(string,BindingFlags) 查找 属性。此函数似乎没有实现名称隐藏,而相应的 GetField(string,BindingFlags) 却实现了。

您将需要使用 GetProperties 并选择您想要的 属性,然后使用需要 PropertyInfo.

Expression.Property 重载

对于那些感兴趣的人......
它在行

上失败

GetType(Inherited(Of String)).GetProperty("Prop1")

Imports System.Linq.Expressions
Imports NUnit.Framework

<TestFixture> Public Class ExpressionTEst

<Test> Public Sub GetOvrriddenProperyInExpression()

    Dim ex = Expression.PropertyOrField(Expression.Constant(Nothing, GetType(Inherited(Of String))), "field1")
    Dim ex2 = Expression.PropertyOrField(Expression.Constant(Nothing, GetType(Inherited(Of String))), "t2")

    GetType(Inherited(Of String)).GetField("field1")
    GetType(Inherited(Of String)).GetProperty("Prop1")

    Dim ex3 = Expression.PropertyOrField(Expression.Constant(Nothing, GetType(Inherited(Of String))), "Prop1")

End Sub

Public Class Base
    Public field1 As Object
    Public Property Prop1 As Object

    Public Overridable Property t2 As String
End Class

Public Class Inherited(Of T)
    Inherits Base

    Public Overrides Property t2 As String
        Get
            Return MyBase.t2
        End Get
        Set(value As String)
            MyBase.t2 = value
        End Set
    End Property

    Public Shadows field1 As T
    Public Shadows Property Prop1 As T

End Class

结束Class

正如@NetMage 和@IvanStoev 所说,不一致之处在于 GetField 与 GetProperty

这段代码解决了..有点

Expression memberValue = null;
            if (m.MemberType == MemberTypes.Property)
            {
                PropertyInfo propInfo = null;
                foreach(var p in m.DeclaringType.GetProperties())
                {
                    if (p.Name == m.Name)
                    {
                        //Just pick the first one. 
                        propInfo = p;
                        break;
                    }
                }
                memberValue = Expression.Property(Expression.Convert(valueObject, objType), propInfo);
            }
            else
            {
                memberValue = Expression.Field(Expression.Convert(valueObject, objType), m.Name);
            }