2017-03-02 46 views
3

我正在使用反射來創建lambda函數。它適用於我嘗試使用的大多數項目,但是在其中一個屬性中,它會一直拋出不明確的匹配異常。Expression.PropertyOrField中的AmbiguousMatchException

代碼如下所示。當它遇到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); 
} 
+3

也許你有多個屬性(或字段)具有相同的名稱,但不同的套管(如「TestProp」和「testProp」)。 – Evk

+0

@Evk是對的,我用'decimal?'測試了它,它有和沒有相同名稱但不同外殼的屬性。 Unfortunatley,我不知道如何告訴'Expression.PropertyOrField'區分大小寫。 –

+0

嗯,更改名稱確實解決了問題。雖然沒有其他名稱相同的屬性(除了小寫字母,前面有一個「_」)。謝謝。 – user2657943

回答

2

我看只有一個辦法這樣的例外可能在這種情況下拋出:你有相同名稱但不同的外殼多個屬性,就像這樣:

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以區分大小寫的方式進行搜索。

但是我會爭辯說,擁有多個同名的屬性無論如何都是不好的做法,應該避免。

+0

它確實與層次有關。謝謝。我不知道'Expression.PropertyOrField'也查找屬性的屬性。 – user2657943

相關問題