문제

나는 다음과 같은 작업을 수행하고 싶습니다.

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

비리를 따라가는 중 링크, 이 스니펫을 얻었습니다(더 이상 사용되지 않는 메소드를 제거하도록 수정됨). 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;

}  
도움이 되었습니까?

해결책

다음과 같이 즉시 컴파일을 사용하여 이 예 보여줍니다.

아니면 서두르다, 이는 정확히 같은 이유입니다.

다른 팁

나는 오픈 소스 프로젝트를 작성했습니다. 다이나믹 익스프레스, 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);

내 작업은 Scott Gu 기사를 기반으로 합니다. http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .

오래된 주제이지만 이것이 인터넷 검색 시 나타나는 첫 번째 스레드 중 하나라는 점을 고려하면 여기에 업데이트된 솔루션이 있습니다.

당신이 사용할 수있는 표현식을 평가하기 위한 Roslyn의 새로운 스크립팅 API.

NuGet을 사용하는 경우 종속성을 추가하면 됩니다. Microsoft.CodeAnalytic.CSharp.스크립팅.제공한 예제를 평가하는 방법은 다음과 같이 간단합니다.

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

이는 분명히 스크립팅 엔진의 비동기 기능을 사용하지 않습니다.

의도한 대로 평가된 결과 유형을 지정할 수도 있습니다.

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

고급 코드 조각을 평가하고, 매개변수를 전달하고, 참조, 네임스페이스 등을 제공하려면 위에 링크된 Wiki를 확인하세요.

자신의 프로젝트에서 코드와 어셈블리를 구체적으로 호출하려는 경우 다음을 사용하는 것이 좋습니다. C# CodeDom 코드 제공자.

다음은 C#에서 문자열 식을 동적으로 평가하기 위해 제가 알고 있는 가장 널리 사용되는 접근 방식 목록입니다.

마이크로소프트 솔루션

Microsoft 이외의 솔루션(문제가 있는 것은 아닙니다)

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에서 실행됩니다.아직 캐싱 시스템이 없으므로 스크립트는 실행될 때마다 다시 컴파일됩니다.나는 몇 가지 간단한 테스트를 수행했으며 디스크에서 스크립트를 로드하는 것을 포함하여 내 컴퓨터에서 약 0.7초 만에 매우 간단한 "Hello World" 스크립트를 컴파일했습니다.0.7초는 스크립팅 시스템에 적합하지만 사용자 입력에 응답하기에는 너무 느릴 수 있습니다. 이 경우 Flee와 같은 전용 파서/컴파일러가 더 나을 수 있습니다.

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

RegEx 및 XPathNavigator를 사용하여 표현식을 평가하는 방법도 있는 것 같습니다.아직 테스트할 기회는 없었지만 런타임에 코드를 컴파일하거나 사용할 수 없는 라이브러리를 사용할 필요가 없었기 때문에 마음에 들었습니다.

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

나는 그것을 시도하고 그것이 효과가 있는지 나중에 말할 것입니다.저도 Silverlight에서 해볼 생각인데 너무 늦어서 지금 거의 잠이 들었습니다.

C#은 기본적으로 Eval 메서드를 지원하지 않지만 C# 코드를 평가할 수 있는 C# 평가 프로그램이 있습니다.런타임 시 C# 코드를 평가하는 기능을 제공하고 많은 C# 문을 지원합니다.실제로 이 코드는 모든 .NET 프로젝트 내에서 사용할 수 있지만 C# 구문 사용으로 제한됩니다.내 웹사이트를 살펴보세요. http://csharp-eval.com, 자세한 내용을 확인하세요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top