2012-04-04 13 views
1

Warum die folgenden DisplayContents nicht (wird nicht kompilieren) für eine Arraylist, wie es IEnumerable erbt bilden)Arraylist und IEnumerable Abfrage

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

Welche Art von Fehler erhalten Sie? – yoozer8

+0

Sorry Fehler ist "Argument 1: kann nicht konvertieren von 'System.Collections.ArrayList' zu 'System.Collections.Generic.IEnumerable '" – Noel

Antwort

7

ArrayList implementiert IEnumerable, aber nicht die generische IEnumerable<T>. Dies ist zu erwarten, da ArrayList weder generisch noch an einen bestimmten Typ gebunden ist.

Sie müssen den Parametertyp Ihrer DisplayContents-Methode von IEnumerable<T> zu IEnumerable ändern und dessen Typparameter entfernen. Die Artikel Ihrer Sammlung werden an übergeben, die alle object akzeptieren können.

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

Oder noch besser, benutze 'ArrayList' überhaupt nicht, weil es unnötig ist. Verwenden Sie 'List ' wenn Sie * wirklich * müssen, und die Antwort darauf ist wahrscheinlich "nein". –

+0

Wie funktioniert es dann für ein Array? h. es funktioniert für string [] – Noel

+0

@Noel: Arrays implementieren 'IEnumerable ' für ihren spezifischen Typ. 'ArrayList' ist ein veralteter Typ, es gab keinen Grund, eine andere Schnittstelle hinzuzufügen, als Generika eingeführt wurden. –

0

ArrayList implementiert IEnumerable, aber nicht generisch IEnumerable<T>

UPDATE: Diese arbeiten:

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

Nun, eine schnelle Überprüfung von the docs erzählt mir, dass ArrayList nicht implementiert IEnumerable<T>, sondern implementiert IEnumerable, die Sinn macht als ArrayList ist ein verkümmertes Artefakt aus den Tagen vor Generika und hat nur wenige echte Anwendungen heute.

Es gibt wirklich keinen Grund, ArrayList überhaupt zu verwenden. Sie können zumindest eine List<object> verwenden, aber welches Problem löst das? Sofern Sie nicht unbedingt eine Sammlung von zufälligen Typen benötigen, die keine gemeinsame Schnittstelle implementieren können und/oder nicht in einen neuen Typ gruppiert werden können, verwenden Sie einen spezifischeren generischen Parameter.

+1

Mit anderen Worten, verwenden Sie nicht ARRAYLIST. Verwenden Sie die Liste

+0

Nein, ernsthaft. Wenn Sie heute mit ArrayList Code schreiben, WERDE ICH SIE. –

+0

@MichaelPaulukonis: Ja, bitte. Ich sehe es zu sehr in Foren. –

-3

Wenn Sie die Rufleitung an das zu ändern, es funktioniert:

DisplayContents(l3.ToArray()); 
+0

Es funktioniert, weil Arrays implementieren IEnumerable , aber das hilft dem OP überhaupt nichts verstehen. –

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

Blick auf Ihren Code. Sie übergeben DisplayContents() eine Liste von Zeichenfolgen, aber Sie sagen es eine Liste von ArrayLists zu erwarten.

Sie wahrscheinlich nur DisplayContents<string>(l3) gemeint zu nennen, aber wie alle anderen schon erwähnt hat, das wird nicht funktionieren, da Arraylist nicht die allgemeine IEnumerable<T> implementieren, es implementiert nur IEnumerable.

Sie könnten stattdessen rufen

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

Dies funktioniert, weil string[]IEnumerable<string> implementiert.

0

Wie wäre es mit einer Erweiterungsmethode?

/// <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); 
    } 
} 
Verwandte Themen