1

これは、私が学ぼうとしていることに対する言葉遣いの悪い質問かもしれないので、私がやろうとしていることを説明します。次の式を使用して作成されている次のリストがあります。

var showIndexes = from item in lItems
                               where WildcardString.IsMatch(item.RecordId.ToString(), filter) ||
                                     WildcardString.IsMatch(item.Tokens.ToString(), filter) ||
                                     WildcardString.IsMatch(string.Format("{0}:{1}", item.OwnerID.SystemName, item.OwnerID.Port.ToString()), filter) ||
                                     WildcardString.IsMatch(item.ChildID.UserName, filter) ||
                                     WildcardString.IsMatch(item.TypeOfLicense.ToString(), filter) ||
                                     WildcardString.IsMatch(item.ExpiryTime.DateTime.ToLocalTime().ToString(), filter)
                               select item.RecordId.ToString();

この式を関数に入れ、「where」で使用される制約を 1 つのパラメーターとして渡したいと考えています。どうすればこれを達成できますか? ファイル属性を操作するとき (異なる属性列挙型を選択するとき) にビットごとの OR を使用して同様の機能を見たことがあるので、デリゲートのグループを "where" ルールとして受け取る独自の関数を作成できるはずです。

関連する場合、WildcardString.IsMatch(string, string) はブール関数です。また、まったく同じことを実行する3つの異なる関数がありますが、リストが異なるため、これを1つの関数に減らし、リストと選択ルールを渡す方法を学びたいのです.

4

3 に答える 3

3

述語を定義するだけitemです。ブール値を受け取って返す関数です。

itemそれがタイプRecordfilterあり、スコープ内にあると仮定します。

Func<Record, bool> predicate = r =>
    WildCardString.IsMatch(r.RecordId.ToString(), filter) ||
    WildCardString.IsMatch(...);

次にpredicate、ファーストクラスの値として扱い(保存、パラメーターとして渡すなど)、次のようにフィルター処理できIEnumerable<Record>ます

var filtered = enumerable.Where(predicate);
于 2013-01-29T13:38:55.033 に答える
2

where 部分を関数にリファクタリングするだけです。

public bool MyIsMatch(MyType item, String filter)
{
    return
    WildcardString.IsMatch(item.RecordId.ToString(), filter) ||
    WildcardString.IsMatch(item.Tokens.ToString(), filter) ||
    WildcardString.IsMatch(string.Format("{0}:{1}", item.OwnerID.SystemName, item.OwnerID.Port.ToString()), filter) ||
    WildcardString.IsMatch(item.ChildID.UserName, filter) ||
    WildcardString.IsMatch(item.TypeOfLicense.ToString(), filter) ||
    WildcardString.IsMatch(item.ExpiryTime.DateTime.ToLocalTime().ToString(), filter);
}

そして、それを呼び出します:

var showIndexes = from item in lItems where MyIsMatch(item, filter) select item.ToString();
于 2013-01-29T13:39:25.847 に答える
1

有効な値のリストを取る Is.Match のバージョンを作成できます

public static bool IsMatch(IEnumerable<object> values, filter) {
    return values.All(v => IsMatch(v.ToString(),filter))
}

あなたの場合、このように使用します

var values = new object[]{
                    item.RecordId,
                    item.Tokens,
                    string.Format("{0}:{1}", item.OwnerID.SystemName, item.OwnerID.Port),
                    item.ChildID.UserName
                    item.TypeOfLicense
                    item.ExpiryTime.DateTime};

var showIndexes = from item in lItems
                  where WildcardString.IsMatch(values,filter)
                           select item.RecordId.ToString();

各アイテムからを削除するIEnumerable<object>代わりに使用することを選択しましたが、ValueTyped 値をボックス化およびボックス化解除するため、これにはかなりのコストがかかります。特定されたパフォーマンス クリティカル パス上にある場合は、代わりに使用する必要がありますIEnumerable<string>.ToString()IEnumerable<string>

于 2013-01-29T13:44:51.997 に答える