14

2 つの Linq 式の結果を構成したいと考えています。それらは形で存在します

Expression<Func<T, bool>>

したがって、私が構成したい 2 つは、基本的に、両方ともブール値を返す (T 型の) パラメーターのデリゲートです。私が作成したい結果は、ブール値の論理評価になります。おそらく拡張メソッドとして実装するので、構文は次のようになります。

Expression<Func<User, bool>> expression1 = t => t.Name == "steve";
Expression<Func<User, bool>> expression2 = t => t.Age == 28;
Expression<Func<User, bool>> composedExpression = expression1.And(expression2);

そして、後で私のコードで、構成された式を評価したい

var user = new User();
bool evaluated = composedExpression.Compile().Invoke(user);

いくつかの異なるアイデアを試してみましたが、思っていたよりも複雑ではないかと心配しています。これはどのように行われますか?

4

1 に答える 1

20

次に例を示します。

var user1 = new User {Name = "steve", Age = 28};
var user2 = new User {Name = "foobar", Age = 28};

Expression<Func<User, bool>> expression1 = t => t.Name == "steve";
Expression<Func<User, bool>> expression2 = t => t.Age == 28;

var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());

var result = Expression.Lambda<Func<User, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);

Console.WriteLine(result.Compile().Invoke(user1)); // true
Console.WriteLine(result.Compile().Invoke(user2)); // false

拡張メソッドを介してこのコードを再利用できます。

class User
{
  public string Name { get; set; }
  public int Age { get; set; }
}

public static class PredicateExtensions
{
  public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,Expression<Func<T, bool>> expression2)
  {
    InvocationExpression invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());

    return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
  }
}

class Program
{
  static void Main(string[] args)
  {
    var user1 = new User {Name = "steve", Age = 28};
    var user2 = new User {Name = "foobar", Age = 28};

    Expression<Func<User, bool>> expression1 = t => t.Name == "steve";
    Expression<Func<User, bool>> expression2 = t => t.Age == 28;

    var result = expression1.And(expression2);

    Console.WriteLine(result.Compile().Invoke(user1));
    Console.WriteLine(result.Compile().Invoke(user2));
  }
}
于 2008-09-10T08:38:22.883 に答える