2012-04-04 4 views
1

なぜ次DisplayContentsは、ArrayListのために(文句を言わないコンパイル)は動作しません)のArrayListとIEnumerableを問い合わせ、それはIEnumerableをを形成継承するよう

public class Program 
    { 
     static void Main(string[] args) 
     { 
      List<int> l = new List<int>(){1,2,3}; 
      DisplayContents(l); 

      string[] l2 = new string[] {"ss", "ee"}; 
      DisplayContents(l2); 

      ArrayList l3 = new ArrayList() { "ss", "ee" }; 
      DisplayContents < ArrayList>(l3); 

      Console.ReadLine(); 
     } 

     public static void DisplayContents<T>(IEnumerable<T> collection) 
     { 
      foreach (var _item in collection) 
      { 
       Console.WriteLine(_item); 
      } 
     } 
    } 
+0

どのようなエラーが表示されますか? – yoozer8

+0

「Argument 1: 'System.Collections.ArrayList'から 'System.Collections.Generic.IEnumerable 'に変換できません」 – Noel

答えて

7

ArrayListは、IEnumerableを実装していますが、汎用のIEnumerable<T>は実装していません。 ArrayListは一般的でも特定のタイプにも束縛されていないため、これは予想されます。

DisplayContentsメソッドのパラメータタイプをIEnumerable<T>からIEnumerableに変更し、タイプパラメータを削除する必要があります。あなたのコレクションのアイテムはConsole.WriteLineに渡され、objectを受け入れることができます。

public static void DisplayContents(IEnumerable collection) 
{ 
    foreach (var _item in collection) 
    { 
     Console.WriteLine(_item); 
    } 
} 
+3

また、 'ArrayList'を使わないでください。 *本当に*必要な場合は 'List 'を使ってください。その答えはおそらく "no"です。 –

+0

配列の場合はどうしたらうまくいくのですか?つまり、string [] – Noel

+0

@ Noel:arraysで動作します。配列は、特定の型の 'IEnumerable 'を実装しています。 'ArrayList'は古くなっているタイプなので、ジェネリックが導入されたときに別のインターフェースを追加する理由はありませんでした。 –

0

ArrayListは、一般的なIEnumerable<T>

UPDATE IEnumerableを実装していますが、ない: この動作します:

public static void DisplayContents(IEnumerable collection) 
{ 
    foreach (var _item in collection) 
     Console.WriteLine(_item); 
} 
4

よく、the docs私にはArrayListIEnumerable<T>を実装していませんが、ArrayListは一般的な前の日の痕跡であり、今日はほとんど使用されていないので意味をなさないIEnumerableを実装しています。

実際にArrayListを使用する理由はありません。少なくともList<object>を使用できますが、どのような問題が解決しますか?共通インターフェイスを実装できない/できない、新しいタイプにグループ化できないランダムタイプのコレクションを絶対に必要としない限り、より具体的な汎用パラメータを使用します。

+1

つまり、ARRAYLISTは使用しないでください。リストを使用

+0

いいえ、真剣に。 ArrayListを使用してコードを書く場合は、私はあなたをスマックにします。 –

+0

@MichaelPaulukonis:はい、してください。私はフォーラムでそれをあまりにも参照してください。 –

-3

あなたはこれに呼び出し元の行を変更した場合、それが動作します:あなたのコードで

DisplayContents(l3.ToArray()); 
+0

配列はIEnumerable を実装しているため動作しますが、OPが何かを何か理解するのに役立つわけではありません。 –

0
ArrayList l3 = new ArrayList() { "ss", "ee" };    
DisplayContents<ArrayList>(l3); 

ルック。文字列のリストをDisplayContents()に渡していますが、ArrayListsのリストが必要です。

おそらくDisplayContents<string>(l3)を呼び出すことを意味しますが、ArrayListは汎用IEnumerable<T>を実装していないため、他の人は既に述べたように、それは動作しません。IEnumerableしか実装していません。

代わりstring[]IEnumerable<string>を実装しているためこれは動作します

DisplayContents<string>((string[])l3.ToArray(typeof(string))); 

呼び出すことができます。

0

拡張方法はどうですか?

/// <summary> 
/// Projects any <see cref="IEnumerable"/>, e.g. an <see cref="ArrayList"/> 
/// to an generic <see cref="IEnumerable{T}"/>. 
/// </summary> 
/// <typeparam name="T">The type to project to.</typeparam> 
/// <param name="source">The source sequence.</param> 
/// <param name="map">The mapping function.</param> 
/// <returns>A sequence of <typeparamref name="T"/>.</returns> 
public static IEnumerable<T> Select<T>(this IEnumerable source, Func<object, T> map) 
{ 
    foreach(var item in source) 
    { 
     yield return map(item); 
    } 
} 
関連する問題