2016-05-14 5 views
3

実行時に動的に式ツリーを構築しようとしています。この式はいくつかのメソッドを呼び出し、あるメソッドの結果を次のメソッドに渡します。最後のメソッドは何かを返します。単一のメソッド呼び出し式を難なく構築して実行することはできますが、式でこれらのメソッドを連鎖させる方法を理解することはできません。実行時に式ツリーを呼び出すメソッドを呼び出す

下記の簡略化されたコード。ライブコードには、さまざまなメソッド呼び出しとパラメータを持つメソッドがあります。

私はここで式1 &式2

var uncompileable = HostNumber.GetHostNumber("Bleacher").HostStatus.GetHostStatus(); // Status = "Online" 

using System; 
using System.Linq.Expressions; 

namespace SO 
{ 
    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      ConstantExpression param1 = Expression.Constant(Convert.ChangeType("Bleacher", typeof(String)));  
      MethodCallExpression expression1 = Expression.Call(typeof(HostNumber), "GetHostNumber", null, new Expression[] { param1 }); 

      ConstantExpression param2 = Expression.Constant(Convert.ChangeType("45", typeof(int))); 
      MethodCallExpression expression2 = Expression.Call(typeof(HostStatus), "GetHostStatus", null, new Expression[] { param2 }); 

      var invokee = Expression.Lambda(expression1).Compile(); 
      var result = invokee.DynamicInvoke(); 

     } 
    } 

    public class HostNumber 
    { 
     public static int GetHostNumber(string hostName) 
     { 
      return 45; 
     } 
    } 

    public static class HostStatus 
    { 
     public static string GetHostStatus(int hostNumber) 
     { 
      return "Online"; 
     } 
    } 
} 
+0

'HostNumber.GetHostNumber(" Bleacher ")HostStatus.GetHostStatus()は、' GetHostNumber'が整数を返し、HostStatusプロパティを持つオブジェクトではないため、コンパイルしません。 –

+0

私は知っています。私はちょうどその行を追加して、私が達成しようとしていることのコンセプトを示しました。 HostNumber.GetHostNumber( "Bleacher")(45)の出力は、HostStatus.GetHostStatus()に渡されます。ありがとう、 – Canacourse

答えて

1

を組み合わせることにより、実行時にこれに相当するものを取得しようとしている概念的には、あなたがそれを行うだろうかです:

var expression = 
    Expression.Call(
     typeof (HostStatus).GetMethod("GetHostStatus", BindingFlags.Public | BindingFlags.Static), 
     Expression.Call(
      typeof (HostNumber).GetMethod("GetHostNumber", BindingFlags.Public | BindingFlags.Static), 
      Expression.Constant("Bleacher", typeof (string)))); 

var func = Expression.Lambda<Func<string>>(expression).Compile(); 

var result = func(); 

ところで、なぜあなたはこれをやっているのかはわかりません。なぜ静的な式を構築してコンパイルしていますか?

+0

ありがとうございます。これらのメソッド呼び出しは、構成ファイル(DSL)から解析されます。 – Canacourse

+0

あなたは大歓迎です。そうですか。メソッド名は静的ではないので、動的です。 –

+0

ありますが、式には1つのメソッド呼び出しまたは3つまでの呼び出しが含まれている可能性があります。メソッド呼び出しにはパラメータがないか、最大2つまで可能です。したがって、コードが複雑になる可能性があります。表現を一緒にマージするためにエクスプレッションビジターを使用しようとしましたが、途中で失われました。 – Canacourse

関連する問題