なぜ Predicate<T> ではなく Func<T,bool> なのでしょうか?
質問
これはただの好奇心旺盛な質問で、誰かが良い答えを持っているかどうか疑問に思っていました。
.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トしていきたいという思いから、この緩和の問題の互換性のない委譲です。皆さんの代表すもとかなるだけにマッチングに基づくパラメータを返します。
な解決の問題が Func
( Action
)を持つことができない out
または ref
パラメータがあまり一般使用します。
更新: のコメントSvish言うのです:
まだ、スイッチングパラメータのタイプから Funcを述語と 裏があるようには見えませんせ 違うの?少なくともそれはまだ統 ています。
あり、プログラムにのみ付け手法の代表者として第一線の Main
機能です。コンパイラの黙々と生成コード新しい委譲オブジェクトに転送の方法です。なので私 Main
機能が変化 x1
型 ExceptionHandler2
ることなく問題です。
しかし、第二線のように割り当ての委譲他に限ります。ものを考える第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
は完全に良いものに割り当てる p
や f
変数として長いと思います。ができない割り当ての変数に関す。
アドバイスはAction<...>
とFunc<...>
を使用することです - 一つの利点は、あなたが「述語」は何を意味するか知っていれば「Predicate<T>
は」唯一の意味があるということである - 。そうしないとのシグニチャーを見つけるために、オブジェクトブラウザ(など)を見てする必要があります。
逆Func<T,bool>
は、標準的なパターンに従います。すべての用語を理解する必要はありません - - 私はすぐに、これはT
を取り、bool
を返す関数であることを伝えることができます。ちょうど私の真実のテストを適用する。
「述語」については、これはOKだったかもしれないが、私は標準化しようとする試みを高く評価しています。また、その地域の関連法とパリティをたくさんすることができます。