2016-05-17 7 views
1

コードインライン(または使用してリフレクション)を評価します。残念ながら、値はすべてCodeDom.CodeStatements内にあります。は、私は、問題の核心に取得するには、この多くを簡略化してきた

だから私は、文字通り、このようなコードを使用して値のために魚を持っている:

public static void SetPropertyValue(this object obj, string propName, object value) 
     { 
     obj.GetType().GetProperty(propName).SetValue(obj, value, null); 
     } 

しかし、この:コードは、リフレクションを使用していることを

static string GenerateCode(CodeStatementCollection statements, Control control) 
     { 
     var writer = new StringWriter(); 

     var compiler = new CSharpCodeProvider(); 

     foreach (CodeStatement statement in statements) 
     { 
      var codeAssignStatement = statement as System.CodeDom.CodeAssignStatement; 

      var left = codeAssignStatement?.Left as System.CodeDom.CodePropertyReferenceExpression; 

      if (left == null) 
      { 
       continue; 
      } 

      var right = codeAssignStatement.Right as System.CodeDom.CodeObjectCreateExpression; 

      if (right == null) 
      { 
       continue; 
      } 

      var expressionWriter = new StringWriter(); 
      compiler.GenerateCodeFromExpression(right,expressionWriter,null); 
      var expression = expressionWriter.ToString(); 

      control.SetPropertyValue(left.PropertyName, expression); 

      compiler.GenerateCodeFromStatement(statement, writer, null); 

     } 

     return writer.ToString(); 
     } 

はお知らせ、SetPropertyValueが実際に拡張メソッドであります値がリテラル値であり、式ではない場合にのみ機能します。

実行時に、私がCodeDomステートメントから得ているものは式であり、コントロールもボタンです。

Button.Location = New System.Drawing.Point(12,12);

したがって、上記のコードサンプルでは、​​表現=「新しいSystem.Drawing.Point(12,12)」

今、私が最初にIF文の一連の実行する必要がありますする必要はありませんタイプを決定する。

リフレクションを使用して式に基づいてプロパティを設定することはできますか?

そうでなければ、これを取り除くために.netのEval関数を使用することはできますか?

答えて

2

スクリプトからコードを作成するには、メソッドを動的にコンパイルする必要があります。

まず、メソッドをMethodInfoにコンパイルするだけです。 これを実現する方法を作成できます。

public static MethodInfo CreateMethodInfo(string script, string className, string methodName) 
{ 
    using (var compiler = new CSharpCodeProvider()) 
    { 
     var parms = new CompilerParameters 
     { 
      GenerateExecutable = false, 
      GenerateInMemory = true, 
      ReferencedAssemblies = { "System.Drawing.dll" } 
     }; 
     return compiler.CompileAssemblyFromSource(parms, script) 
      .CompiledAssembly.GetType(className) 
      .GetMethod(methodName); 
    } 
} 

これを実行すると、このように使用できます。

var script = "public class Methods{public static System.Drawing.Point DoSomething(){return new System.Drawing.Point(12, 12);}}"; 

var method = CreateMethodInfo(script, "Methods", "DoSomething"); 

今でmethod変数は、あなたのMethodInfoを保持しているので、あなたはそれを呼び出す必要があります。

Button.Location = (Point)method.Invoke(null, null); 
+0

あなたはスマートです!これは完全に機能しました。どうもありがとうございました! –

0

LINQ表現を試すことができると思います。 https://msdn.microsoft.com/en-us/library/bb335710(v=vs.110).aspx

変更するには、方法下記の好きな:

public static void SetPropertyValue(this object obj, string propName, Expression<Func<T, object>> value) 

設定し、式の中で、デリゲート関数をコンパイルしてSetPropertyValueでそれを呼び出します()。

関連する問題