1

私は式ツリーを初めて使用し.Where()、Linq のメソッドからエンティティへのクエリで使用する動的式を構築しようとしています。や などの Expression メソッドを明示的に呼び出すと、すべてが機能するようExpression.Equal(exp, exp)になりExpression.GreaterThan(exp, exp)ます。私がやりたいことは、Expression.Method をハード コードする必要がないため、メソッド名を含む文字列を渡して、これを使用して動的にビルドできるようにすることです。以下に例を示します。これは可能ですか?どう進めていいのか途方に暮れています。

 static void Main(string[] args)
 {

   int i = 1;
   int? iNullable = 1;
   object o = 1;
   int j = 2;

   ParameterExpression pe1 = Expression.Parameter(typeof(int));
   ParameterExpression pe2 = Expression.Parameter(typeof(int));

   //explicitly creating expression by calling Expression.Method works fine
   Expression call = Expression.Equal(pe1, pe2);
   var f = Expression.Lambda<Func<int, int, bool>>(call, pe1, pe2).Compile();

   Console.WriteLine(f(i, i));
   Console.WriteLine(f((int)iNullable, i));
   Console.WriteLine(f(i, (int)o));
   Console.WriteLine(f(i, j));

   //I want to use a dynamic Expression method instead of Expression.Equal
   //so that it could be substituted with Expression.GreaterThan etc.
   String expressionMethod = "Equal";

   //get the method
   MethodInfo method = typeof(Expression)
     .GetMethod(expressionMethod, 
      new[] { typeof(Expression), typeof(Expression) });

   //I'm lost ....

    Console.ReadKey();

 }
4

1 に答える 1

2

メソッドを呼び出すだけでよいことがわかりました。他の誰かが恩恵を受けることができる場合に備えて、このソリューションを公開します。

class Program
{
  static void Main(string[] args)
  {

    int i = 1;
    int? iNullable = 1;
    object o = 1;
    int j = 2;

    ParameterExpression pe1 = Expression.Parameter(typeof(int));
    ParameterExpression pe2 = Expression.Parameter(typeof(int));

    //explicitly creating expression by calling Expression.Method works fine
    Expression call = Expression.Equal(pe1, pe2);
    var f = Expression.Lambda<Func<int, int, bool>>(call, pe1, pe2).Compile();

    Console.WriteLine(f(i, i));
    Console.WriteLine(f((int)iNullable, i));
    Console.WriteLine(f(i, (int)o));
    Console.WriteLine(f(i, j));

    //I want to use a dynamic Expression method instead of Expression.Equal
    //so that it could be substituted with Expression.GreaterThan etc.
    List<String> expressionMethod = new List<string>(){"Equal", "GreaterThan"};

    foreach (String s in expressionMethod) DynamicExpression(s, j, i); 


    Console.ReadKey();
  }

  static void DynamicExpression(String methodName, int n1, int n2)
  {
    ParameterExpression pe1 = Expression.Parameter(typeof(int));
    ParameterExpression pe2 = Expression.Parameter(typeof(int));

    //get the method
    MethodInfo method = typeof(Expression)
        .GetMethod(methodName,
         new[] { typeof(Expression), typeof(Expression) });

    //Invoke
    Expression dynamicExp = (Expression)method.Invoke(null, new object[] { pe1, pe2 });
    var f = Expression.Lambda<Func<int, int, bool>>(dynamicExp, pe1, pe2).Compile();

    Console.WriteLine("Result for " 
         + n1.ToString() + " " 
         + methodName + " " + n2.ToString() + ": " + f(n1, n2));
  }
}
于 2013-02-12T06:46:57.307 に答える