就拿這個代碼創建一個呼叫被叫AddNumbers
方法的自定義委託:從方法體提取代碼並使用表達式內聯執行它?
public static int AddNumbers(int a, int b)
{
return a + b;
}
static void Main(string[] args)
{
ParameterExpression
arga = Expression.Parameter(typeof(int)),
argb = Expression.Parameter(typeof(int));
MethodCallExpression result = Expression.Call(typeof(Program_ModelBinding).GetMethod("AddNumbers"), arga, argb);
var deli = Expression.Lambda(result, arga, argb).Compile() as Func<int, int, int>;
Console.WriteLine(deli(2, 4));
}
編譯爲:
.Lambda #Lambda1<System.Func`3[System.Int32,System.Int32,System.Int32]>(
System.Int32 $var1,
System.Int32 $var2) {
.Call ModelBinding.Program_ModelBinding.AddNumbers(
$var1,
$var2)
}
然而,爲了減少繁瑣並保持堆棧整齊,我會喜歡能夠內聯AddNumbers
方法,以便其方法體在代碼本身內編譯,就像我這樣做:
BinaryExpression result = Expression.Add(arga, argb);
這將彙編本:
.Lambda #Lambda1<System.Func`3[System.Int32,System.Int32,System.Int32]>(
System.Int32 $var1,
System.Int32 $var2) {
$var1 + $var2
}
我還會注意到我不希望有工作過的對象實例,即使方法是非靜態的。我只想提取方法體,然後在我的代碼中內聯使用它。
我以某種方式認爲System.Reflection.Emit
命名空間有我正在尋找的答案,但我不知道繼續哪個方向。
我很確定使用'Expression','MethodBuilder','DynamicMethod'等生成的方法永遠不會被內聯。你能做的最好的事情實際上是在你的表達式中生成這個語句並編譯它,但我想這不會給你想要的。 – jamespconnor
@jamespconnor正確,那是行不通的。這個想法是,如果我改變了具體方法中的代碼,生成的代碼將引入新的方法體。我不想在兩個地方重複邏輯,這樣我也必須修改表達式代碼以匹配具體方法正在做的事情。 – oscilatingcretin
你可以創建'Expression'作爲'static',然後在兩個地方使用它?例如'private static readonly表達式> AddNumbers =(a,b)=> a + b;' –
jamespconnor