2012-03-23 24 views
7

İş mantığını okuduğum ve değişkenleri gerçek değerlerle değiştirdiğim bir yer var ve sonuç almak için bunu değerlendirmem gerekiyor. Şu anda bunu yapmak için bcParser kullanıyorum ve excel formatı olarak yazılan tüm mantık için gayet iyi çalışıyor.İfadeler için dinamik bir ifade ağacı oluşturmak mümkün mü?

Bana atılan eğri top, eğer durumexcel gibi olmayacaksa, C# if (cond) { true; } else { false;}'un yerini alacaktır, bu daha mantıklı ve bakımı kolaydır. Tüm değişkenleri el değmeden önce değiştirdiğim için, tek yapmam gereken şeyi değerlendirmek. Şu anda bu problemi mantığı C# yöntemlerine aktararak ve değerlendirmeyi kullanarak değerlendiriyorum ve aynı zamanda çalışıyorum.

Başka bir seçenek var mı diye merak ediyorum, koşulu olan her biri için kod yazmak istemiyorum ve çalışma zamanında değerlendirmek istiyorum. Bir çeşit belirteci belirteci oluşturabilir ve C# yerel ifade değerlendirmesini arayabilir ve hesaplamayı yapıp yapamayacağımı merak ediyordum. Keşif ağaçlarını anlamadım, bu yaklaşımla mümkün görünüyor. oraya gitmeden önce bilmek isterim ki, bu mümkün mü? Sağol,

+3

İfade ağaçları dizeyi ayrıştırmanıza yardımcı olmaz. [CodeDom] 'a bakmak isteyebilirsiniz (http://msdn.microsoft.com/en-us/library/y2k85ax6.aspx) veya [Rosalyn] (http://msdn.microsoft.com/en-us/roslyn). –

cevap

5

Evet!

Anahtar, System.Linq.Expressions ad alanını kullanıyor. Programlı olarak, kodunuzda veya ayrıştırıcınızı değiştirerek, bir Delegate içine derleyebilirsiniz. Bu API, bir DynamicAssembly'un içindeki Delegate'u derler; bu, derlenmiş ifadelerin, tamamen kaldırılırken çöp toplayıcı tarafından bellekten kaldırılabileceği anlamına gelir.

True 
False 

ifadesi önemli bir performans isabet olabilen bir Lambda'ya içinde derlendiği adım, istediğiniz olacak: Bu çıktı üretir

var b = true; 
Func<bool> condition =() => b; 
Action trueExpression =() => { Console.WriteLine(true); }; 
Action falseExpression =() => { Console.WriteLine(false); }; 

var e = Expression.Condition(
    Expression.Invoke(Expression.Constant(condition)), 
    Expression.Invoke(Expression.Constant(trueExpression)), 
    Expression.Invoke(Expression.Constant(falseExpression))); 

var λ = Expression.Lambda(e).Compile(); 

b = true; 
λ.DynamicInvoke(); 

b = false; 
λ.DynamicInvoke(); 

: Burada

çok basit bir örnektir derlenmiş lambdalarınız için bir önbellekleme stratejisi geliştirmek için. Yine de buna değer, DynamicInvoke kullanarak derlenmiş lambda çağırmak çok hızlı. Neredeyse ön derlemiş olsaydın kadar hızlıydı. Bu teknik, CodeDom kod nesnesini (derlemeyi yapmak için başka bir süreç gerektirir) kullanılmasından çok daha hızlıdır ve yüklenemez montajlar üretmenin en büyük yararına sahiptir.

Bunun tek kısıtlaması, bu API'ye sahip Türler oluşturamazsınız. Kendinizi ifadelere ve ifadelere sınırlamak zorundasınız. Ancak oldukça güçlü, bu DLR'nin sihirli cesaretleri.

+1

Lambda sembolünü nasıl edinirsiniz? İstemek! – usr

+1

Kopyalama yapıştır! Bu sadece bir unicode karakteri. C# 'da geçerlidir. –

İlgili konular