質問

これはただの好奇心旺盛な質問で、誰かが良い答えを持っているかどうか疑問に思っていました。

.NET Framework クラス ライブラリには、たとえば次の 2 つのメソッドがあります。

public static IQueryable<TSource> Where<TSource>(
    this IQueryable<TSource> source,
    Expression<Func<TSource, bool>> predicate
)

public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, bool> predicate
)

なぜ彼らは使うのか Func<TSource, bool> の代わりに Predicate<TSource>?のようです Predicate<TSource> によってのみ使用されます List<T> そして Array<T>, 、 その間 Func<TSource, bool> ほぼ全員が使用しています Queryable そして Enumerable メソッドと拡張メソッド...どうしたの?

役に立ちましたか?

解決

その間 Predicate 同時に導入されました List<T> そして Array<T>, 、.net 2.0 では、 Func そして Action バリアントは .net 3.5 からのものです。

それでそれらは Func 述語は主に LINQ 演算子の一貫性のために使用されます。.net 3.5 以降の使用について Func<T> そして Action<T>ガイドラインに記載されている内容:

新しい LINQ 型を使用してください Func<> そして Expression<> カスタム代表者と述語の代わりに

他のヒント

私は前にこれを不思議に思っていました。私はPredicate<T>デリゲートが好き - それは素晴らしく、記述的です。しかし、あなたはWhereのオーバーロードを考慮する必要があります:

Where<T>(IEnumerable<T>, Func<T, bool>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)

それはあなたにも、エントリのインデックスに基づいてフィルタリングすることができます。それは、いいと一貫性のあるのに対します:

Where<T>(IEnumerable<T>, Predicate<T>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)

ではないでしょう。

確かに、この利用 Func 代わりに特定の委員はC#の扱いを別途申告の代表として全く異なる。

Func<int, bool>Predicate<int> と同一の引数と戻り値の型な課題対応しました。それらを組み合わせると、図書館宣言された独自の委譲タイプのための各委譲パターンは、図書館できないだろうとの互換ない限り、ユーザーに挿入します"架橋"の代表を行う換。

    // declare two delegate types, completely identical but different names:
    public delegate void ExceptionHandler1(Exception x);
    public delegate void ExceptionHandler2(Exception x);

    // a method that is compatible with either of them:
    public static void MyExceptionHandler(Exception x)
    {
        Console.WriteLine(x.Message);
    }

    static void Main(string[] args)
    {
        // can assign any method having the right pattern
        ExceptionHandler1 x1 = MyExceptionHandler; 

        // and yet cannot assign a delegate with identical declaration!
        ExceptionHandler2 x2 = x1; // error at compile time
    }

を促すことで皆様の利用Funcトしていきたいという思いから、この緩和の問題の互換性のない委譲です。皆さんの代表すもとかなるだけにマッチングに基づくパラメータを返します。

な解決の問題が FuncAction)を持つことができない out または ref パラメータがあまり一般使用します。

更新: のコメントSvish言うのです:

まだ、スイッチングパラメータのタイプから Funcを述語と 裏があるようには見えませんせ 違うの?少なくともそれはまだ統 ています。

あり、プログラムにのみ付け手法の代表者として第一線の Main 機能です。コンパイラの黙々と生成コード新しい委譲オブジェクトに転送の方法です。なので私 Main 機能が変化 x1ExceptionHandler2 ることなく問題です。

しかし、第二線のように割り当ての委譲他に限ります。ものを考える第2回委譲タイプとまったく同じパラメータと戻り値の型は、コンパイラエラーを CS0029: Cannot implicitly convert type 'ExceptionHandler1' to 'ExceptionHandler2'.

そこで明:

public static bool IsNegative(int x)
{
    return x < 0;
}

static void Main(string[] args)
{
    Predicate<int> p = IsNegative;
    Func<int, bool> f = IsNegative;

    p = f; // Not allowed
}

私の方法 IsNegative は完全に良いものに割り当てる pf 変数として長いと思います。ができない割り当ての変数に関す。

「なぜ?」のために - (3.5以上)で

アドバイスはAction<...>Func<...>を使用することです - 一つの利点は、あなたが「述語」は何を意味するか知っていれば「Predicate<T>は」唯一の意味があるということである - 。そうしないとのシグニチャーを見つけるために、オブジェクトブラウザ(など)を見てする必要があります。

Func<T,bool>は、標準的なパターンに従います。すべての用語を理解する必要はありません - - 私はすぐに、これはTを取り、boolを返す関数であることを伝えることができます。ちょうど私の真実のテストを適用する。

「述語」については、これはOKだったかもしれないが、私は標準化しようとする試みを高く評価しています。また、その地域の関連法とパリティをたくさんすることができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top