6

私はこのようなものを持っています:

public Expression<Func<Message, bool>> FilterData()
{
    switch (this.operatorEnum)
    {
        case FilterParameterOperatorEnum.EqualTo:
            return message => !string.IsNullOrEmpty(message.Body) &&
                              message.Body
                                     .Equals(this.value, StringComparison.InvariantCultureIgnoreCase);

        case FilterParameterOperatorEnum.NotEqualTo:

            return message => !string.IsNullOrEmpty(message.Body) &&
                              !message.Body
                                     .Equals(this.value, StringComparison.InvariantCultureIgnoreCase);

        case FilterParameterOperatorEnum.Contains:

            return message =>
                    !string.IsNullOrEmpty(message.Body) &&
                    message.Body.IndexOf(this.value,
                                   StringComparison.InvariantCultureIgnoreCase) >= 0;

        case FilterParameterOperatorEnum.DoesNotContain:
            return message =>
                    !string.IsNullOrEmpty(message.Body) &&
                    message.Body.IndexOf(this.value,
                                   StringComparison.InvariantCultureIgnoreCase) == -1;


    }
}

ご覧のとおり、これはMessage.Body

クラスの他の文字列プロパティで同じことを行うにはどうすればよいでしょうかMessage。そのコードをすべて複製したくありません。

どういうわけかプロパティを渡すことでそれを行う方法はありますか?

4

4 に答える 4

3

プロパティ値を取得する式を別のラムダ式に含めます。

public Expression<Func<Message, bool>> FilterData(Func<Message, string> retrievePropValueFunc)

フィルター式で、その新しいラムダ式を呼び出すことができます (例として 1 つだけ示します)。

return message => !string.IsNullOrEmpty(retrievePropValueFunc(message))
        && retrievePropValueFunc(message)
                .Equals(this.value, StringComparison.InvariantCultureIgnoreCase);

プロパティにアクセスするには、パラメーターBodyに渡します。ご覧のとおり、これを変更して、他のプロパティを取得するために別のラムダ式を渡すこともできます。message => message.BodyretrievePropValueFunc

于 2013-05-21T09:58:06.203 に答える
1

式を完全に手動で作成してみると、プロパティ名を文字列として指定できるようになります。これは完全な解決策ではなく、テストもされていませんが、私の言いたいことを理解するための出発点になるかもしれません:

var parameter = Expression.Parameter(typeof(Message), "o");
var getname = Expression.Property(parameter, "Body");

var isnullorempty = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, getname));
var compare = Expression.Equal(getname, Expression.Constant("thisvalue"));

var combined = Expression.And(isnullorempty, compare);

var lambda = Expression.Lambda(combined, parameter);

したがって、「Body」をパラメーターとして受け入れるように関数を変更し、最後にラムダを次のようにキャストします。

expression<func<Message, bool>>

ただし、ラムダを正確に作成するための構文を持っていない可能性があります。

于 2013-05-21T11:29:36.787 に答える
0

非常に迅速で汚いアプローチは、enumプラスのある種の魔法になる可能性があります。

public enum FilterTarget { Body, AnyOtherProp };
public Expression<Func<Message, bool>> FilterData(FilterTarget filterTarget)
{
    string toBeFiltered = string.Empty;

    switch(filterTarget)
    {
        case FilterTarget.Body : 
        { toBeFiltered = message.Body; } break;
        case FilterTarget.AnyOtherProp : 
        { toBeFiltered = message.AnyOtherProp; } break;
        default: 
        { 
            throw new ArgumentException(
                string.Format("Unsupported property {0}", filterTarget.ToString()
            ); 
        } 
    }

    switch (this.operatorEnum)
    {
        case FilterParameterOperatorEnum.EqualTo:
            return message => !string.IsNullOrEmpty(toBeFiltered) &&
                              toBeFiltered.Equals(this.value, StringComparison.InvariantCultureIgnoreCase);

      /* CUT: other cases are similar */
    }
}

FilterDataメソッドをさらに凝ったものにして、 を受け入れるparams FilterTarget[]ようにして、マルチフィルタリング機能を得ることができます (頭のてっぺんから、コードは含まれていません)。

使用法:

var aFilterDataResult = FilterData(FilterTarget.Body);    
var anotherFilterDataResult = FilterData(FilterTarget.AnyOtherProp);
...
于 2013-05-21T11:47:47.800 に答える
0

メッセージの代わりにプロパティを受け取るように関数を変更するだけです。

または、難しい方法で、プロパティ名にもう 1 つのパラメーターを渡し、リフレクションを使用して選択します。

すべてのオプションを変更するよりも、1 つのオプションだけを編集します。

    public Func<Message, string, bool> FilterData()
    {
        return (message, propName) =>
        {
            var prop = message.GetType().GetProperty(propName);

            if(prop != null){
                var propValue = (string)prop.GetValue(message,null);
                return !string.IsNullOrEmpty(propValue) && ...;
            }
            return false;
        };

    }
于 2013-05-21T09:55:45.490 に答える