2009-07-14 12 views
1

以下の例では、GetPeopleを使用するクライアントコードが各ユーザーの名前と年齢をコンソールに表示したい場合、リフレクションを使用して、そのクエリにIEnumerable(Of Person)が含まれていることを確認してからキャストする必要がありますそのようなものとして、その特性を得ることができます。IEnumerable <T>でIEnumerableを使用する必要がある場合は、

Public Function GetPeople() As IEnumerable 
    Dim query = From p As Person In People.AsEnumerable() _ 
       Select p 
    Return query 
End Function 

のIEnumerableの一般的な形式は、はるかに有益で便利なクライアントに思える:

Public Function GetPeople() As IEnumerable(Of Person) 
    Dim query = From p As Person In People.AsEnumerable() _ 
       Select p 
    Return query 
End Function 

私は理由がある確信している - そう、なぜIEnumerableを、これまでのIEnumerableよりも優先されるだろうが、(Tの) ?

ありがとうございました。

答えて

8

私が見る限り、決してありません。 IEnumerable<T>IEnumerableを継承しているので、IEnumerable<T>は、Tについて知っていることを呼び出し元に伝えますが、ジェネリックスの前に書かれた関数はコレクションを使用することができます。

非汎用IEnumerableが存在する理由は歴史的です。

+0

一般に、IEnumerable.GetEnumerator()を明示的なインターフェイスの実装として実装し、IEnumerable 。暗黙の実装として.GetEnumerator()を使用します。 (非ジェネリックコードの場合は)後方互換性がありますが、クラスは通常完全に汎用です – thecoop

2

IEnumerableIEnumerable<T>以上に使用した唯一の時間は、LINQクエリと匿名オブジェクトを扱うときです。以下の(不自然)の例を考えてみましょう:

class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

IEnumerable<object> GetFirstNames(IEnumerable<Person> people) 
{ 
    return from p in people 
      select new 
      { 
       Name = p.FirstName 
      }; 
} 

これは、次のエラーを生成します。

error CS0266: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<object>'. An explicit conversion exists (are you missing a cast?)

をしかし、あなたはIEnumerableGetFirstNames()の戻り値の型を変更した場合、それがコンパイルされます。

+1

個人的には、署名をIEnumerable として残し、新しい{Name = p.FirstName}を選択するようにコードを変更します。 .Cast (); – mquander

0

ジェネリックをご利用いただけない場合、つまり.NET 1.1を使用している場合。

0

おそらく、戻り値ではありません。それ以外の場合は、可能な場合はいつでも使用してください。 IEnumerableはより一般的なIEnumerable <>であるため、より一般的なコードになります。

例として、IEnumerableのnun-null値を出力するだけの一般的な関数を考えてみましょう。

関連する問題