2016-04-06 9 views
2

現在、私は他のコードを使用しています。があるメソッド内に "ToListAsync()"を含むIEnumerableを返す

public async MyMethod Task<IEnumerable<MyResult>> FindResults() 
{ 
// some code here 
var ret = await repository.BusinessObjects.ToListAsync() 

return ret; 

} 

質問:私はこのようなものを見たとき、これが初めてではないではありません、それはMyMethodは戻り型でIEnumerableをを使用して逆の結果が既に列挙されているので、それはですこのように保つのが良い? リストを使用する方が良いでしょうか?

(私はそれがまた、非非同期操作に適用されると思いますが、私はこれに私は、私は念のために働くのコードでそれを見る方法を表示することにしました)

+0

は何 'IList'、' IEnumerable'と 'ICollection' http://www.claudiobernasconi.ch/2013/07/22/when-to-use-ienumerable-icollection-については、この取得の考えを読んで考えてみましょう'ilist-and-list/ – Eldho

答えて

3

技術的に言えば、このようにコードを書くことに問題はありません。上記の具体的なコード例では、List<>インスタンスを返してもメソッドの戻り値の型がIEnumerable<>の場合は(技術的に)問題ありません。パフォーマンスヒットはなく、実際に返されるタイプはまだList<>です。

これは良いことではないと言われています。 が可能な最も汎用的/抽象的な型を受け入れるように、メソッドを構造化する必要があるという設計ガイドラインがあります(の制限内で、各メソッドのパラメータとしてオブジェクトを使用しないでください) )。

参考資料として、Vladimir KhorikovによるReturn the most specific type, accept the most generic typeと題されたこの記事を参照してください。これはまた、以前に頼まれました。Is it better to return the most specific or most general type from an action method?を参照してください。

これは、第1の署名List<MyResult>が実際に返される型であると仮定して、次の2つの署名が良い練習になることを意味します。第2の例では、更新を行っている間は入力。

public async Task<List<MyResult>> FindResultsAsync(); 
public async Task UpdateAsync(IEnumerable<MyResult> itemsForUpdate); 
+0

原則として同意しますが、 'List 'を返す程度ではありません。これにより、異なるコレクション型(ObservableCollection など)を返すようにメソッド定義を変更することができなくなります。代わりに 'IList '(または 'ICollection ')を返すほうがよいでしょう。 – Douglas

+0

@Douglas - 私たちはどちらも一致していると思います。メソッドシグニチャ(インタフェースや他の型を介して)が(あなたの例を使って) 'ObservableCollection <>'のようなものを返すことができるならば、あなたは100%正しいです、 'IList <>'が最良の戻り値のタイプ'ObservableCollection <>'と 'List <>'の間の最も特殊な型であるからです(他の可能性がある場合)。したがって、上記の原則は依然として有効です。また、実装が柔軟性を保つことができるように、多くの場合、インタフェースがコンクリート型よりも良い戻り型の選択肢になると思います。 – Igor

+0

実装が決して変更されず、戻り値の型が常に静的であることがわかっている場合、ほとんどの場合、戻り値の型自体が最適な選択肢になります。 – Igor

0

これはあなたのユースケースに依存します。 IEnumerableは優れた抽象化を提供しますが、使用に応じてパフォーマンスコストが発生する可能性があります。

リストを非同期で作成し、列挙型のコンシューマとして(潜在的に)繰り返し使用するのは、一度繰り返すことが本当です。

私は個人的に(私の使用の場合)、あなたがパフォーマンスに重要でないパスでのみ示したパターンを使用します。結果はすでに列挙されていて、それがこのようにそれを維持する方が良いですので、初期化

0

MyMethod戻り値の型にIEnumerableを使用することは逆効果ではないですか? Listを使用する方が良いでしょうか?

どのように違いがあるのか​​、それが問題なのか分かりません。通常、この問題は、EFクエリのような遅延コレクションを返すときに発生し、複数の反復が複数のデータベース呼び出しを引き起こします。

Listを返しているので、複数の繰り返しが問題になることはありません。 に変更してListを返すようにしたい場合は、複数回繰り返しても安全ですが、実際には何も変更されません。

より基本型を返すことに利点があります。戻り値の型がListまたはIEnumerable doesnのであるかどうかが、複数の列挙についてのあなたの懸念の文脈で(例えば、それはあなたがList以外の異なるコレクション型を返すことができます)問題ありません。

+0

' IEnumerable'を使用している場合、そのインターフェースは 'Add()'や 'Remove()'メソッドを含んでいません。コレクションが複数のレイヤーを通過しても変更されないようにします。 'List'または' IEnumerable'の両方で、クエリはすでにマテリアライズされています。一番下のインタフェースを返すだけでは良いことではありませんか?私のメソッドが 'IList'を返す場合、私は' List'か 'Array'を返すことができます。我々がリストを返すならば、それは実装ではなく実装にプログラミングしている。 – Eldho

+0

@エルドー・トゥルーは、返されたコレクションでクライアントができることを変えるだろうが、OPの関心事は、複数回列挙するほどではないと思う。これは 'List'では大きな問題ではない。 –

+0

そういう意味では、リストは最善の賭けでなければなりません。 – Eldho

関連する問題