Expression.PropertyOrField 中的 AmbiguousMatchException

use*_*943 5 c# linq reflection lambda

我正在使用反射来创建一个 lambda 函数。它适用于我尝试使用的大多数项目,但是在其中一个属性上它不断抛出 Ambiguous Match Exception。

代码看起来像这样。当它击中时发生错误Expression.PropertyOrField。我使用的属性是 类型decimal?。我认为这可能与它是可空类型的事实有关,但我不确定。

public static LambdaExpression CreateExpression(Type type, string propertyName, ref Type returnType)
{
    var param = Expression.Parameter(type, "x");
    Expression body = param;
    foreach (var member in propertyName.Split('.'))
    {
        body = Expression.PropertyOrField(body, member);
    }
    returnType = body.Type;
    return Expression.Lambda(body, param);
}
Run Code Online (Sandbox Code Playgroud)

Evk*_*Evk 6

我只看到在这种情况下可能抛出此类异常的一种方式:您有多个名称相同但大小写不同的属性,如下所示:

public class Test {
    public decimal? testProp { get; set; }
    public decimal? TestProp { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

或字段:

public class Test {
    public decimal? testProp;
    public decimal? TestProp;
}
Run Code Online (Sandbox Code Playgroud)

请注意,具有相同名称的属性也可能在任何父类中向上层次结构:

public class BaseTest {
    public decimal? testProp { get; set; }
}

public class Test : BaseTest {        
    public decimal? TestProp { get; set; } // also fails
}
Run Code Online (Sandbox Code Playgroud)

原因是Expression.PropertyOrField这样做是为了搜索所需的属性:

type.GetProperty(propertyOrFieldName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy);
Run Code Online (Sandbox Code Playgroud)

注意BindingFlags.IgnoreCaseBindingFlags.FlattenHierarchy。所以你不能告诉Expression.PropertyOrField以区分大小写的方式进行搜索。

但是,我认为拥有多个具有相同名称的属性无论如何都是一种不好的做法,应该避免。