3

DisplayNameFor(x=>x.Title)ASP.Net MVC にはヘルパーがあります。動作が似ているものを実装したいと思います。

Userクラス (u=>u.Birthdateまたは u=>u.Name)、オペランド (Greater、Less、Equal) および次のような値に基づいて式を受け入れ、式を返すメソッドが必要ですDateTime.Nowu=>u.Birthdate > DateTime.Now

結果の式を断片から手動で構築する必要があることを理解しています。頭を包み込めないのは、プロパティ式の受け渡しと処理です。

編集: または
のようなメソッドを呼び出したい
GetFilterPredicate(u=>u.Birthdate,FilterOps.GreaterThan,DateTime.Parse("01.01.2013")
GetFilterPredicate(u=>u.SomeIntProperty,FilterOps.Equals,2)

更新: この質問の解決策とコレクション プロパティのフィルタリングを含むレポを作成しました https://github.com/Alexander-Taran/Lambda-Magic-Filters

4

4 に答える 4

5

これはあなたのニーズを満たしていますか?

[TestClass]
public class UnitTest1
{
    public Expression<Predicate<T>> GetFilterPredicate<T, R>(Expression<Func<T, R>> selector, FilterOps operand, R value)
    {
        var parameter = selector.Parameters[0];

        var left = selector.Body;
        var right = Expression.Constant(value);

        var binaryExpression = Expression.MakeBinary(operand.ToExpressionType(), left, right);
        return Expression.Lambda<Predicate<T>>(binaryExpression, parameter);
    }

    [TestMethod]
    public void TestMethod1()
    {
        var p1 = this.GetFilterPredicate((User u) => u.Birthday.TimeOfDay.Hours, FilterOps.LessThan, 12);
        var p2 = this.GetFilterPredicate((User u) => u.Size, FilterOps.Equal, 180);

        var user = new User() { Birthday = new DateTime(2000, 1, 1), Size = 180 };

        Assert.IsTrue(p1.Compile()(user));
        Assert.IsTrue(p2.Compile()(user));
    }
}

public enum FilterOps
{
    GreaterThan, LessThan, Equal
}
public static class MyExtensions
{
    public static ExpressionType ToExpressionType(this FilterOps operand)
    {
        switch (operand)
        {
            case FilterOps.GreaterThan: return ExpressionType.GreaterThan;
            case FilterOps.LessThan: return ExpressionType.LessThan;
            case FilterOps.Equal: return ExpressionType.Equal;
            default: throw new NotSupportedException();
        }
    }
}

public class User { public DateTime Birthday { get; set; } public int Size { get; set; } }
于 2013-11-05T13:48:17.923 に答える
3

これがあなたの目指しているものだと思います。

public Func<User, bool> MyMethod<TProperty>(Expression<Func<User, TProperty>> func, ComparisonPredicate op, TProperty value)
{


}

public enum ComparisonPredicate
{
    Equal,
    Unequal,
    LessThan,
    LessThanOrEqualTo,
    GreaterThan,
    GreaterThanOrEqualTo
}
于 2013-11-05T12:58:02.240 に答える
0

以下のメソッドは、ブール値の戻り値を持つバイナリ式を生成します

Expression<Predicate<TObject>> 
     GenerateAssignExpression<TObject, TProperty>(
         Expression<Func<TObject, TProperty>> expression,
         ExpressionType op, 
         TProperty Value)
    {   
        return Expression.Lambda<Predicate<TObject>>(
            Expression.MakeBinary(op, expression, Expression.Constant(Value)),
            getExpression.Parameters[0]);
    }

一般的な戻り値の型が必要な場合は、をに変更するだけPredicate<TObject>ですFunc<TObject,TReturn>(「述語」の両方の出現を置き換える必要があります

于 2013-11-05T13:57:45.097 に答える