Doğrudan bir yöntemi çağıran bir ifade ağacı oluşturmak mümkün mü? Örneğin, aşağıdaki yöntemi göz önünde bulundurun:Bir yöntemi çağıran bir ifade ağacı oluşturma
public static int MyFunc(int a, int b)
{
return a + b;
}
Ben parametreleri a = 1 ve b = 2 ile MyFunc çağıran bir ifade ağaç oluşturmak istiyoruz. Bunu yapmanın bir yolu, yansıma ile; yansıma yavaş ve çalışma zamanı hataları içine derleme zamanı hataları ne olması gerektiği döner çünkü
var c1 = Expression.Constant(1);
var c2 = Expression.Constant(2);
var expr = Expression.Call(typeof(Program).GetMethod("MyFunc"), c1, c2);
Ancak bu dezavantajlıdır.
yerine aşağıdaki yaklaşımı kullanabilirsiniz:
Expression<Func<int, int, int>> lambda = (a, b) => MyFunc(a, b);
var expr = Expression.Invoke(lambda, c1, c2);
Ama bu doğrudan aramak yerine bir lambda ifadede yöntemi sarar çünkü ne istiyorum hala değil.
iyi bir çözüm
böyle bir temsilci dayalı olabilir:Func<int, int, int> del = Program.MyFunc;
var expr = Expression.Invoke(del, c1, c2);
Maalesef del
bir temsilci ziyade bir ifadesidir çünkü derlemek gelmez. Delegeden bir ifade oluşturmanın herhangi bir yolu var mı? (Derleme zamanında delege hedefini bildiğimi unutmayın, bu nedenle burada açıklanan esnekliğe ihtiyacım yoktur: Expression Trees and Invoking a Delegate.)
Çağrısız bir çözüm, çağrıldıkları sürece iyi olmaz Hedef yöntemi mümkün olduğunca doğrudan.
Güncelleme: Bu da çalışır, ama yine de yansıması dayanır:
Func<int, int, int> del = Program.MyFunc;
var expr = Expression.Call(del.Method, c1, c2);
En azından derleme sırasında sorunlar yakalamak için daha olasıdır. Ama hala çalışma zamanı fiyatını ödüyor, değil mi?
Kullanım durumu hakkında daha fazla bilgi yararlı olacaktır :) ör. Size verdiğiniz örneklerle, bir 'Func' (… Funk ) 'den geçiyor olabilirsiniz (ve derleme zamanında hedefi biliyorsunuz), bu yüzden' İfade 'ağacı ne için gereklidir? –
porges
Bir ifadeyi derlemek, yansımaların tepesini cüceler. İfadeyi yaptığınızda sadece yansımayı bir kez yaptığınızdan, maliyeti göz ardı edilebilir. – Gabe