문제

내가 할 수 있습니다 eval("something()"); 코드를 실행하려면 동적으로 자바 스크립트에서.방법은 없을 경우 이와 같은 작업을 수행 C#?

예를 들어 내가 무엇을 하려고 하:나는 변수의 정수(말 i 다)및 여러 특성에 의해 이름:"Property1","Property2","Property3",등등.지금,나는 몇 가지 작업을 수행에"속성 "속성 값에 따라 i.

이것은 정말 간단합니다.어떤 방법으로 C#?

도움이 되었습니까?

해결책

불행하게도,C#지 않는 동적 언어와 같습니다.

무엇을 할 수 있는,그러나,을 만드는 C#소스 코드 파일의 전체 클래스고 모든 것,그리고 그것을 실행을 통해 CodeDom 공급자를 위한 C#컴파일을 어셈블리로,다음을 실행합니다.

이 포럼에 게시 MSDN 포함되어 있는 대답으로 몇 가지 예제 코드는 아래 페이지를 다소:
을 만들 익명의 방법은 문자열에서?

내가 이 말을 거의 매우 좋은 해결책이지만,그건 어쨌든이 가능합니다.

어떤 종류의 코드가 기대에는 문자열?는 경우에 그것은 미성년자 하위 집합의 올바른 코드,예를 들어 단지 수학적인 표현할 수 있습는 다른 대안이 존재합니다.


편집:잘 가르치는 나에게 질문을 읽을 철저하게 처음이다.Yes,반영할 수 있을 것입을 줄 당신은 어떤 도움이 여기에.

당신이 문자열을 분할하여;첫째로,개인 속성을 사용할 수 있습니다,다음 코드를 얻을 PropertyInfo 객체를 특정 속성 클래스에 대해,다음 사용하는 개체를 조작하는 특정 개체입니다.

String propName = "Text";
PropertyInfo pi = someObject.GetType().GetProperty(propName);
pi.SetValue(someObject, "New Value", new Object[0]);

링크: PropertyInfo.SetValue 방법

다른 팁

를 사용하는 로슬린 스크립트 API(상 여기에서 샘플):

// add NuGet package 'Microsoft.CodeAnalysis.Scripting'
using Microsoft.CodeAnalysis.CSharp.Scripting;

await CSharpScript.EvaluateAsync("System.Math.Pow(2, 4)") // returns 16

실행할 수도 있습니다 모든 부분의 코드:

var script = await CSharpScript.RunAsync(@"
                class MyClass
                { 
                    public void Print() => System.Console.WriteLine(1);
                }")

참조 코드가 생성되 이전에 실행됩:

await script.ContinueWithAsync("new MyClass().Print();");

하지 않습니다.할 수 있는 리플렉션을 사용하여 달성하기 위해 무엇을 원하지만,그것은 없을 거에서와 같이 간단합니다.는 경우 예를 들어,설정하고 싶어 프라이빗 필드는 개체의 무언가에 사용할 수 있습니다 이 기능:

protected static void SetField(object o, string fieldName, object value)
{
   FieldInfo field = o.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
   field.SetValue(o, value);
}

이는 평가에 따라 기능을 수 있습니다.나는 그것을 사용하는 익명으로 변환 기능을(람다 식)문자열.출처: http://www.codeproject.com/KB/cs/evalcscode.aspx

public static object Eval(string sCSCode) {

  CSharpCodeProvider c = new CSharpCodeProvider();
  ICodeCompiler icc = c.CreateCompiler();
  CompilerParameters cp = new CompilerParameters();

  cp.ReferencedAssemblies.Add("system.dll");
  cp.ReferencedAssemblies.Add("system.xml.dll");
  cp.ReferencedAssemblies.Add("system.data.dll");
  cp.ReferencedAssemblies.Add("system.windows.forms.dll");
  cp.ReferencedAssemblies.Add("system.drawing.dll");

  cp.CompilerOptions = "/t:library";
  cp.GenerateInMemory = true;

  StringBuilder sb = new StringBuilder("");
  sb.Append("using System;\n" );
  sb.Append("using System.Xml;\n");
  sb.Append("using System.Data;\n");
  sb.Append("using System.Data.SqlClient;\n");
  sb.Append("using System.Windows.Forms;\n");
  sb.Append("using System.Drawing;\n");

  sb.Append("namespace CSCodeEvaler{ \n");
  sb.Append("public class CSCodeEvaler{ \n");
  sb.Append("public object EvalCode(){\n");
  sb.Append("return "+sCSCode+"; \n");
  sb.Append("} \n");
  sb.Append("} \n");
  sb.Append("}\n");

  CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
  if( cr.Errors.Count > 0 ){
      MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText, 
         "Error evaluating cs code", MessageBoxButtons.OK, 
         MessageBoxIcon.Error );
      return null;
  }

  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.SomeMethod() : service.AnotherMethod()";

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

parsedExpression.Invoke(5);

내 작업에 기반한 스콧 Gu 문서 http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .

모두 확실히 작동합니다.개인적으로 특정 문제,나는 아마 조금 다른 방법으로 접근하고 있습니다.어쩌면 뭔가 다음과 같다:

class MyClass {
  public Point point1, point2, point3;

  private Point[] points;

  public MyClass() {
    //...
    this.points = new Point[] {point1, point2, point3};
  }

  public void DoSomethingWith(int i) {
    Point target = this.points[i+1];
    // do stuff to target
  }
}

을 사용할 때와 같은 패턴이,당신은 조심해야는 데이터가 저장된 참조로 아닌 값입니다.다시 말해서,이것을 하지 않는 프리미티브와 함께.당신을 사용하여 그들의 큰 부풀어준다.

내가 깨달았는지 정확하게 질문,하지만 질문되었습 꽤 잘 대답하고 나는 생각 어쩌면 다른 방법은 도움이 될 수 있습니다.

지 않아요 지금 당신이 절대적으로 실행하려는 C#문,하지만 당신은 이미 자바 스크립트를 실행 문 C#2.0.오픈 소스 라이브러리 Jint 을 할 수 있습니다.그것은 자바 스크립트 인터프리터습니다.NET.패 자바 스크립트 프로그램 내에서 실행됩니다.할 수 있도 C#체 인수로 하는 자동화에습니다.

도하려는 경우에는 표현 평가에 당신의 특성을 체험하실 수 있습니다 NCalc.

당신이 사용할 수 있는 리플렉션을 제공하고 호출니다.무언가 이것을 좋아한다:

object result = theObject.GetType().GetProperty("Property" + i).GetValue(theObject, null);

는 경우가 있는 객체의 속성이라고"개체":)

당신은 또한 당신을 구현할 수있는 컨트롤,다음을 로드하는 html 파일을 포함합니다.

다음 u 에 대한 이동 document.InvokeScript 방법 이 브라우저입니다.의 반환 값 eval 기능을 사로 변환 모든 것을 당신이 필요합니다.

내가 이것에서 여러 프로젝트에 완벽하게 작동합니다.

그것을 희망하는 데 도움이

당신은 그것을 할 수 있으로 시제품 기능:

void something(int i, string P1) {
    something(i, P1, String.Empty);
}

void something(int i, string P1, string P2) {
    something(i, P1, P2, String.Empty);
}

void something(int i, string P1, string P2, string P3) {
    something(i, P1, P2, P3, String.Empty);
}

그래서...

리플렉션을 사용하여 구문 분석하고 평가할 데이터 바인딩 표현에 대한 개체를 수행할 필요는 없습니다.

DataBinder.Eval 방법

작성,패키지 SharpByte.동, 를 단순화하는 작업을 컴파일하고 실행하는 코드를 동적으로.코드가 호출될 수 있는 모든 컨텍스트를 사용하여 개체 연장 방법으로 상세한 .

예를 들어,

someObject.Evaluate<int>("6 / {{{0}}}", 3))

3 을 반환합니다;

someObject.Evaluate("this.ToString()"))

컨텍스트를 반환하는 개체의 문자열 표현은;

someObject.Execute(@
"Console.WriteLine(""Hello, world!"");
Console.WriteLine(""This demonstrates running a simple script"");
");

실행 그 문을 스크립트로,등등.

실행 파일을 얻을 수 있을 사용하여 쉽게 공장 방법에서 볼 수 있듯이,예 -모든 필요한 소스 코드고 목록의 예상 매개 변수 이름의(토큰은 임베디드를 사용하여 트리플-브라켓 표기법과 같은{{{0}}},으로 충돌을 방지하는 문자열입니다.형식()뿐만 아니라 자전거 핸들과 같은 구문):

IExecutable executable = ExecutableFactory.Default.GetExecutable(executableType, sourceCode, parameterNames, addedNamespaces);

각 실행 가능한 개체(스크립트 또는 식)은 스레드에 안전,저장 및 재사용,로그할 수 있도록 지원합니다.에서 스크립트에서는 타이밍 정보를 저장하고 마지막에 예외가 발생한 경우,등등.또한 복사본()메소드를 컴파일에 각을 만들 수 있도록 저렴한 복사본을 즉를 사용하여 실행 가능한 개체를 컴파일 스크립트에서 또는 식으로 템플릿을 만들기 위한 다른 사람입니다.

오버헤드를 실행하는 이미 컴파일 스크립트나 문은 상대적으로 낮에만에서 마이크로초에 겸손한 하드웨어 및 이미 컴파일 스크립트와 표현에 대해 캐시되 재사용할 수 있습니다.

그러려고의 가치는 구조물(클래스)구성원에 의해 그것의 이름입니다.구조되지 않았다.모든 답 작동하지 않을 때까지 마지막으로 그것을 얻:

public static object GetPropertyValue(object instance, string memberName)
{
    return instance.GetType().GetField(memberName).GetValue(instance);
}

이 방법은 값을 반환합의 구성원에 의해 그것의 이름입니다.그것은 작품에서는 정기적인 구조(클래스).

확인할 수 있습니다 Heleonix.반사 라이브러리입니다.그것은 방법을 제공합니다 get/set/invoke 멤버를 동적으로 포함한 중첩된 회원은 경우,또는 회원이 명확하게 정의를 만들 수 있습 get/set(람다로 컴파일을 위임)어떤 이상 빠른 반사:

var success = Reflector.Set(instance, null, $"Property{i}", value);

는 경우 또는 속성의 수는지 끝이없는,당신을 생성할 수 있는 세터 및 chache 들(setters 빠르기 때문 컴파일되는 대리인):

var setter = Reflector.CreateSetter<object, object>($"Property{i}", typeof(type which contains "Property"+i));
setter(instance, value);

Setters 수 있습의 유형 Action<object, object> 그러나 인스턴스와 다를 수 있습니다 runtime,그래서 당신의 목록을 만들 수 있습 setter.

불행하게도,C#없는 기본 시설을 정확히 무엇을 요청하고 있습니다.

그러나 내 C#평가 프로그램으로 허용하지 않을 평가하는 C#코드입니다.제공해 평가하는 C#에 코드를 런타임이 지원하고 많은 C#문입니다.사실,이 코드를 사용할 수 있습니다.NET 프로젝트,그러나,그것은 제한을 사용하여 C#문입니다.에서 봐야,웹사이트 http://csharp-eval.com, 추가 정보.

올바른 응답이 필요 캐시 모든 결과를 유지하 mem0ry 사용량이 낮습니다.

예를 들어 다음과 같이 보일 것입니다

TypeOf(Evaluate)
{
"1+1":2;
"1+2":3;
"1+3":5;
....
"2-5":-3;
"0+0":1
} 

추가 목록

List<string> results = new List<string>();
for() results.Add(result);

save id 에서 사용하는 코드

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