5

だから基本的に私はこの方法を持っています。

public List<Customer> FilterCustomersByStatus(List<Customer> source, string status)
{
    return (List<Customer>)source.Where(c => c.Status == status);
}

キャストできないというエラーが表示されます。

タイプ 'WhereListIterator`1[AppDataAcces.Customer]' のオブジェクトをタイプ 'System.Collections.Generic.List`1[AppDataAcces.Customer]' にキャストできません。

どうして...?基になる型が同じであるため、Enumerable.Where は WhereListIterator の新しいインスタンスを作成します。もしそうなら、なぜ誰かがこれを行うのでしょうか。これは、常に新しいリストを作成する必要があるため、パフォーマンスと機能が不必要に失われるためです (.ToList( )))

4

5 に答える 5

10

Enumerable.Where の新しいインスタンスを作成しますWhereListIterator

はい。

もしそうなら、なぜ誰かがこれをするのでしょうか

遅延ストリーミング動作が許可されるためです。Where消費者が最初または 2 番目のエントリのみを必要とする場合、すべてのリストをフィルタリングする必要はありません。これは LINQ では正常です。

常に新しいリスト (.ToList()) を作成する必要があるため、パフォーマンスと機能が不必要に失われるためです。

その「パフォーマンスと機能の損失」は、設計に起因します。List<Customer>フィルタリング後は必要ありません。変更を加えても意味がないからです。

更新:「なぜそう実装されているIEnumerableのか」ではなく を実装したためIListです。IEnumerableしたがって、それは のように見えIEnumerableます。

さらに、この方法で実装する方がはるかに簡単です。Where上書きしなければならないことを想像してみてくださいIList。返す必要がありIListます。それは何をすべきですか?元のリストでプロキシを返しますか? アクセスするたびに、パフォーマンスが大幅に低下します。フィルタされたアイテムを含む新しいリストを返しますか? するのと同じになりますWhere().ToList()。元のリストを返しますが、一致しないアイテムはすべて削除しますか? それRemoveAllが目的です、なぜ別の方法を作るのですか。

そして、LINQ は機能的にプレイしようとし、オブジェクトを不変として扱おうとすることを忘れないでください。

于 2012-07-29T16:17:31.023 に答える
2

他の人が指摘したようToListに、結果を に変換するには を使用する必要がありますList<T>

その理由は、Where遅延評価されるため、実際にはデータをフィルター処理Whereしないためです。それが行うことは、必要に応じてデータをフィルタリングする を作成することです。IEnumerable

遅延評価にはいくつかの利点があります。より高速である可能性がありWhere、無限IEnumerableの s などで使用できます。

ToList結果を強制的に に変換しList<T>ます。これは、あなたが望むものと思われます。

于 2012-07-29T16:16:41.643 に答える
0

Where 拡張機能はフィルタリングして返すIEnumerable<TSource>ため、 .ToList() を呼び出して元に戻す必要があります

public List<Customer> FilterCustomersByStatus(List<Customer> source, string status)
{
    return source.Where(c => c.Status == status).ToList();//This will return a list of type customer
}
于 2012-07-29T16:13:24.990 に答える
0

IEnumerable と IList の違いは、enumerable にはデータが含まれておらず、新しいデータを要求すると (たとえば、foreach ループを使用して) データを処理する反復子が含まれていることです。一方、リストはデータのコピーです。あなたの場合、リストを作成するために、ToList() メソッドはデータ全体を反復処理し、それらを List オブジェクトに追加します。

計画している使用方法に応じて、どちらにも長所と短所があります。たとえば、データ全体を複数回使用する予定がある場合はリストを使用する必要がありますが、一度使用する予定がある場合、または linq を使用して再度クエリを実行する予定の場合は、列挙可能を選択する必要があります。

編集: Where の戻り値の型が List ではなく WhereListIterator である理由の質問への答えは、Linq の仕組みが原因の 1 つです。たとえば、最初のステートメントの後に別の Where または別の Linq ステートメントがある場合、コンパイラはメソッド チェーン全体を使用して 1 つのクエリを作成し、最終的なクエリの反復子を返します。一方、最初の Where が List を返し、チェーン内の各 Linq メソッドがデータに対して個別に実行される場合。

于 2012-07-29T16:36:15.457 に答える
-1

これを試して:

public List<Customer> FilterCustomersByStatus(List<Customer> source, string status)
{
    return source.Where(c => c.Status == status).ToList();
}
于 2012-07-29T16:12:47.890 に答える