在我的圖書館之一,我有一個從表達式返回的MethodInfo代碼:爲什麼不同版本的.NET(或編譯器)的生成相同的表達不同的表達式樹
public MethodInfo GetMethod(Expression expression)
{
var lambdaExpression = (LambdaExpression)expression;
var unaryExpression = (UnaryExpression)lambdaExpression.Body;
var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
var methodInfoExpression = (ConstantExpression)methodCallExpression.Arguments.Last();
return (MethodInfo)methodInfoExpression.Value;
}
我有一個一系列的輔助功能,使這樣的方法調用以下:
public MethodInfo Func<T, R, A1>(Expression<Func<T, Func<A1, R>>> expression)
{
return GetMethod(expression);
}
這將使語法如下:
var methodInfo = Func<TestClass, bool, string>(x => x.AnInstanceMethodThatTakesAStringAndReturnsABool);
這很好,直到我最近將庫升級到.Net 4.6.1和最新的c#編譯器。
在以前版本的.NET,表達將是下面的形式:
{x => Convert(CreateDelegate(System.Func`2[System.String, System.Boolean], x, Boolean AnInstanceMethodThatTakesAStringAndReturnsABool(System.String)))}
因此我的代碼將查找methodInfoExpression作爲methodCallExpression的最後一個參數。
現在,在淨4.6.1(最新的C#編譯器),編譯器似乎產生不同形式的表達:因爲最後一個參數是不是一個常量表達式
{x => Convert(Boolean AnInstanceMethodThatTakesAStringAndReturnsABool(System.String).CreateDelegate(System.Func`2[System.String, System.Boolean], x))}
我當前的代碼中斷。看着它 - 很容易解決,只需改變
var methodInfoExpression = (ConstantExpression)methodCallExpression.Object;
顯然,實現getMethod功能是相當脆弱的,可作改動編譯器如何生成表達式。我很好奇改變的原因,以及我如何重構GetMethod,以便它對編譯器生成的表達式樹更有彈性。
你應該真的發佈示例代碼,在提供示例時進行編譯。如果您希望幫助更有效地編寫該方法,則應實際描述需要執行的操作,而不是僅顯示其非工作版本。 – Servy