Ben eşdeğer yapmak istiyorum: gibi, anında derleme kullanarakC# ifadesini dinamik olarak nasıl değerlendirebilirim?
private object Eval(string sExpression)
{
CSharpCodeProvider c = new CSharpCodeProvider();
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
StringBuilder sb = new StringBuilder("");
sb.Append("using System;\n");
sb.Append("namespace CSCodeEvaler{ \n");
sb.Append("public class CSCodeEvaler{ \n");
sb.Append("public object EvalCode(){\n");
sb.Append("return " + sExpression + "; \n");
sb.Append("} \n");
sb.Append("} \n");
sb.Append("}\n");
CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString());
if (cr.Errors.Count > 0)
{
throw new InvalidExpressionException(
string.Format("Error ({0}) evaluating: {1}",
cr.Errors[0].ErrorText, sExpression));
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
return s;
}
Bu neden gereklidir? Bu, niyetiniz ne olursa olsun, en iyi tasarımın olduğundan şüphe duyuyorum. Büyük olasılıkla, kod parçacıklarını çalışma zamanında değerlendiren büyük miktarda solucan (güvenlik ve bakım için) açmadan istediğiniz sonuçları üretmek için başka mekanizmalar da vardır. – Wedge
Yazdığım bir DSL'ye ifade doğrulaması eklemenin hızlı ve kirli bir yolunu istedim. Değerlendiriciye beslenen dosyaları kontrol ediyorum, böylece solucanlar kutusu hiçbir zaman açılmıyor;) Ayrıca, sadece bir ifadeye izin veriyorum, herhangi bir İsim ekleyemem/herhangi bir derleme göndermem. Bu kendimi de zarar vermekten alıkoymalıdır! –
Bunu test senaryolarında yapıyorum. Güncellenen sürüm numaralarını değiştiren bir derlemem var. Montaj kodumun montajı yapabilmesi ve dinamik olarak çağırabilmesi için test kodumun meclise "geç bağlı" olmasını isterim. Bu basit bir yansıma meselesidir. Ancak, derlemede belirtilen bir arabirimi uygulamak istediğimde, arabirimin kendisi güçlü bir şekilde (sürüm numarasıyla) adlandırıldığı için, kodun dinamik olarak derlenmesi gerekir. V1.3'ü çağırmak istediğimde IFoo v1.2'yi uygulayan bir kodum olamaz. Dinamik derleme bunu ele alır. – Cheeso