수학적 표현을 평가하는 가장 짧고 가장 짧은 방법
-
08-07-2019 - |
문제
예를 들어 표현식을 평가하기위한 많은 알고리즘이 있습니다.
C# .NET 반사 또는 기타 최신 .NET 기술을 사용하여 수학적 표현식을 평가할 수있는 방법이 있습니까?
해결책
Thomas의 답변에 따르면 실제로 C#에서 직접 (더 이상 사용되지 않은) JScript 라이브러리에 액세스 할 수 있습니다. eval
기능.
using Microsoft.JScript; // needs a reference to Microsoft.JScript.dll
using Microsoft.JScript.Vsa; // needs a reference to Microsoft.Vsa.dll
// ...
string expr = "7 + (5 * 4)";
Console.WriteLine(JScriptEval(expr)); // displays 27
// ...
public static double JScriptEval(string expr)
{
// error checking etc removed for brevity
return double.Parse(Eval.JScriptEvaluate(expr, _engine).ToString());
}
private static readonly VsaEngine _engine = VsaEngine.CreateEngine();
다른 팁
확실히 가능합니다. 그만큼 CodesNippetCompileUnit 클래스는 기본적으로 이것을합니다. 예제 사용 코드를 썼습니다. 이 네임 스페이스를 포함해야합니다.
- System.codedom.compiler;
- System.codedom;
- Microsoft.csharp;
- 시스템 반사;
코드는 다음과 같습니다.
string source = @"
class MyType
{
public static int Evaluate(<!parameters!>)
{
return <!expression!>;
}
}
";
string parameters = "int a, int b, int c";
string expression = "a + b * c";
string finalSource = source.Replace("<!parameters!>", parameters).Replace("<!expression!>", expression);
CodeSnippetCompileUnit compileUnit = new CodeSnippetCompileUnit(finalSource);
CodeDomProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
CompilerResults results = provider.CompileAssemblyFromDom(parameters, compileUnit);
Type type = results.CompiledAssembly.GetType("MyType");
MethodInfo method = type.GetMethod("Evaluate");
// The first parameter is the instance to invoke the method on. Because our Evaluate method is static, we pass null.
int result = (int)method.Invoke(null, new object[] { 4, -3, 2 });
'매개 변수'및 '표현'을 무엇이든 교체하면 일반적인 표현식 평가자가 있습니다.
results.compileDassembly에서 filenotFoundException을 얻으면 스 니펫이 컴파일하지 못했습니다.
System.codedom.codesnippetexpression 클래스를 살펴 보는 것도 가능합니다. 보다 구체적으로 읽는 표현식에 사용되지만 표현 자체를 편집 할 수 없으므로 더 많은 코드를 사용하여 작업 클래스와 메소드를 구축해야합니다. 이것은 어떤 종류의 수업을 생성하는지 프로그래밍 방식으로 조작하려는 경우 유용합니다. CodesNippetCompileUnit은 한 번에 전체 작업 클래스를 생성하는 것이 좋지만 (예를 들어, 더 간단하게), 그것을 조작하려면 불편한 문자열 조작을 수행해야합니다.
컴파일러 서비스를 사용하는 것은 간단하고 효율적인 솔루션이지만, 표현식을 사용자가 입력하는 경우 심각한 보안 문제가 발생합니다. 아무것.
훨씬 더 안전한 또 다른 매우 간단한 솔루션이 있습니다. JScript를 활용하십시오. Eval
기능. 다음 단계를 따라야합니다.
jsmath.js라는 JS 파일을 만듭니다.
class JsMath
{
static function Eval(expression : String) : double
{
return eval(expression);
};
}
클래스 라이브러리로 컴파일하십시오.
jsc /t:library JsMath.js
C# 프로젝트에서 JSMATH 라이브러리를 참조하고 다음과 같이 사용하십시오.
double result = JsMath.Eval(expression);
나를 위해 vici.parser는 매우 잘 작동합니다. 여기에서 확인하십시오 , 지금까지 찾은 가장 유연한 표현 구문자입니다.
(SQL Server 데이터베이스가 제공 한 데이터와 함께 '휴먼 읽기 가능한'비즈니스 규칙을 설정하는 데 사용했습니다)
예를 이용할 수 있으며 개발자의 지원이 매우 좋습니다 (웹 사이트 포럼 확인).
나는 이것이 가장 좋은 방법이라고 생각합니다. Petar Repac의 답변 놀랍습니다. Datacolumn 객체의 '표현'주장을 사용하면 주제를 엄청나게 쉽고 쉽게 해결합니다.
static double Evaluate(string expression)
{
var loDataTable = new DataTable();
var loDataColumn = new DataColumn("Eval", typeof(double), expression);
loDataTable.Columns.Add(loDataColumn);
loDataTable.Rows.Add(0);
return (double)(loDataTable.Rows[0]["Eval"]);
}