سؤال

وأود أن تفعل أي ما يعادل:

object result = Eval("1 + 3");
string now    = Eval("System.DateTime.Now().ToString()") as string

بعد Biri s الرابط, حصلت على هذا مقتطف (تعديل لإزالة طريقة عفا عليها الزمن ICodeCompiler.CreateCompiler():

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;

}  
هل كانت مفيدة؟

المحلول

باستخدام تجميع على الطاير, مثل هذا المثال يظهر.

أو باستخدام الفرار, وهو نفس السبب بالضبط.

نصائح أخرى

كنت قد كتبت مشروع مفتوح المصدر ، ديناميكية Expresso, التي يمكن تحويل النص التعبير الكتابي باستخدام C# بناء الجملة في الوفود (أو شجرة التعبير).النص تعبيرات يتم تحليلها وتحويلها إلى أشجار التعبير دون استخدام تجميع أو التفكير.

يمكنك كتابة شيء من هذا القبيل:

var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");

أو

var interpreter = new Interpreter()
                .SetVariable("service", new ServiceExample());

string expression = "x > 4 ? service.aMethod() : service.AnotherMethod()";

Lambda parsedExpression = interpreter.Parse(expression, 
                        new Parameter("x", typeof(int)));

parsedExpression.Invoke(5);

عملي يعتمد سكوت قو المادة http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .

الموضوع القديم ، ولكن بالنظر إلى أن هذا هو واحد من أول المواضيع تظهر عندما تقوم بأستخدام هنا هو تحديث الحل.

يمكنك استخدام روزلين الجديدة البرمجة API تقييم التعبيرات.

إذا كنت تستخدم NuGet فقط إضافة إلى التبعية مايكروسوفت.CodeAnalysis.CSharp.البرمجة.لتقييم الأمثلة التي قدمتها ، هو بسيطة مثل:

var result = CSharpScript.EvaluateAsync("1 + 3").Result;

ومن الواضح أن هذا لا يجعل استخدام البرمجة المحرك المتزامن القدرات.

يمكنك أيضا تحديد تقييم نتيجة اكتب كما كنت المقصود:

var now = CSharpScript.EvaluateAsync<string>("System.DateTime.Now.ToString()").Result;

تقييم أكثر تقدما مقتطفات الشفرة, تمرير المعلمات ، وتوفير المراجع مساحات وغيرها ، والتحقق من ويكي مرتبطة أعلاه.

إذا كنت تريد على وجه التحديد في قانون الجمعيات في المشروع الخاص بك وأود أن الدعوة باستخدام C# CodeDom CodeProvider.

وهنا لائحة من الأكثر شعبية النهج التي أنا على علم من تقييم تعبيرات سلسلة حيوي في C#.

حلول مايكروسوفت

غير حلول مايكروسوفت (ليس هناك أي شيء خاطئ مع هذا)

using System;
using Microsoft.JScript;
using Microsoft.JScript.Vsa;
using Convert = Microsoft.JScript.Convert;

namespace System
{
    public class MathEvaluator : INeedEngine
    {
        private VsaEngine vsaEngine;

        public virtual String Evaluate(string expr)
        {
            var engine = (INeedEngine)this;
            var result = Eval.JScriptEvaluate(expr, engine.GetEngine());

            return Convert.ToString(result, true);
        }

        VsaEngine INeedEngine.GetEngine()
        {
            vsaEngine = vsaEngine ?? VsaEngine.CreateEngineWithType(this.GetType().TypeHandle);
            return vsaEngine;
        }

        void INeedEngine.SetEngine(VsaEngine engine)
        {
            vsaEngine = engine;
        }
    }
}

ما هي تأثيرات الأداء من فعل هذا ؟

نحن نستخدم نظام يقوم على شيء مثل المذكورة أعلاه, حيث كل C# السيناريو هو تجميع في الذاكرة الجمعية وتنفيذها في فصل AppDomain.لا يوجد نظام التخزين المؤقت بعد ذلك البرامج النصية يتم recompiled كل مرة يتم تشغيلها.لقد فعلت بعض الاختبارات البسيطة جدا بسيطة "مرحبا العالم" سيناريو يجمع في حوالي 0.7 ثانية على الجهاز الخاص بي ، بما في ذلك تحميل البرنامج النصي من القرص.0.7 ثانية على ما يرام بالنسبة البرمجة النظام ، ولكن قد تكون بطيئة جدا في الاستجابة إلى إدخال المستخدم في هذه الحالة مخصصة محلل/مترجم مثل الفرار قد يكون أفضل.

using System;
public class Test
{
    static public void DoStuff( Scripting.IJob Job)
    {
        Console.WriteLine( "Heps" );
    }
}

يبدو أن هناك أيضا طريقة للقيام بذلك باستخدام التعابير المنطقية و XPathNavigator تقييم التعبير.لم يكن لدي فرصة لاختبار ذلك حتى الآن ولكن أحببت نوعا ما لأنها لا تحتاج إلى ترجمة التعليمات البرمجية في وقت التشغيل أو استخدام المكتبات التي لا يمكن أن تكون متاحة.

http://www.webtips.co.in/c/evaluate-function-in-c-net-as-eval-function-in-javascript.aspx

سأحاول ذلك و اقول في وقت لاحق ما اذا كان يعمل.أنوي أيضا أن تحاول ذلك في سيلفرلايت ، ولكن فوات الأوان و أنا شبه نائمة أن تفعل ذلك الآن.

في حين C# لا تملك أي دعم للفحص الأسلوب أصلا ، لدي C# eval البرنامج أن لا تسمح لتقييم التعليمات البرمجية C#.ويوفر تقييم C# كود في وقت التشغيل و يدعم العديد من C# البيانات.في الواقع, هذا الرمز يمكن استخدامها داخل أي .صافي المشروع ، ومع ذلك ، فإنه يقتصر على استخدام C# بناء الجملة.إلقاء نظرة على موقع الويب الخاص بي ، http://csharp-eval.com, ، للحصول على تفاصيل إضافية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top