【问题标题】:AmbiguousMatchException in Expression.PropertyOrFieldExpression.PropertyOrField 中的 AmbiguousMatchException
【发布时间】:2017-03-02 08:47:01
【问题描述】:

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

代码如下所示。当它到达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);
}

【问题讨论】:

  • 可能您有多个属性(或字段)名称相同但大小写不同(如“TestProp”和“testProp”)。
  • @Evk 是对的,我用decimal? 测试了它,有和没有同名但大小写不同的属性。不幸的是,我不知道如何告诉Expression.PropertyOrField 区分大小写。
  • 嗯,改名确实解决了问题。但是没有任何其他具有相同名称的属性(除了一个小写且前面有_ 的属性)。谢谢。

标签: c# linq reflection lambda


【解决方案1】:

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

public class Test {
    public decimal? testProp { get; set; }
    public decimal? TestProp { get; set; }
}

或字段:

public class Test {
    public decimal? testProp;
    public decimal? TestProp;
}

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

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

public class Test : BaseTest {        
    public decimal? TestProp { get; set; } // also fails
}

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

type.GetProperty(propertyOrFieldName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy);

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

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

【讨论】:

  • 确实和层次有关系。谢谢。我不知道Expression.PropertyOrField 也会查看属性的属性。
猜你喜欢
  • 1970-01-01
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多