Feedback

C# - Eine allgemeine Liste (IEnumerable) in ein Array umwandeln

Veröffentlicht von am 11/21/2009
(2 Bewertungen)
Eine Extension-Methode, die jedes Objekt vom Typ System.Collections.IEnumerable (Arrays, Listen, etc.) in ein Array umwandelt.
Jedes Objekt dieses Typs wird nun um die untere generische Methode erweitert, sofern diese für das Objekt "sichtbar" ist.

Beispiel:
System.Collections.Generic.List<int> zahlen = new System.Collections.Generic.List<int>();

for (int i = 0; i < 1000; i++)
{
zahlen.Add(i * 2);
}

System.Collections.IEnumerable list = zahlen;

/// Das Objekt 'list' wird nur als 'System.Collections.IEnumerable'-Objekt
/// angesehen, d.h. es gibt KEINE Methode ToArray(), wie in
/// System.Collections.Generic.List<T> definiert!
int[] intArray = list.ToArray<int>();
using System;
using System.Collections;
using System.Collections.Generic;

namespace MarcelJKloubert
{
    public static class Tools
    {
        #region Methoden
        /// <summary>
        /// Konvertiert eine allgemeine Liste in ein Array aus Objekten
        /// </summary>
        /// <param name="list">Liste</param>
        /// <returns>Liste als Array</returns>        
        public static object[] ToArray(this IEnumerable list)
        {
            return ToArray<object>(list);
        }
        
        /// <summary>
        /// Konvertiert eine allgemeine Liste in ein Array eines bestimmten Typs
        /// </summary>
        /// <typeparam name="T">Zieltyp des Rückgabearrays</typeparam>
        /// <param name="list">Liste</param>
        /// <returns>Liste als Array</returns>        
        public static T[] ToArray<T>(this IEnumerable list)
        {
            if (list is T[])
            {
                // muss nicht umgewandelt werden
                return (T[])list;
            }

            // neue Liste erzeugen
            List<T> result = new List<T>();
            {
                foreach (object item in list)
                {
                    result.Add((T)item);
                }
            }
            return result.ToArray();
        }
        #endregion
    }
}

6 Kommentare zum Snippet

Rainer Hilmer schrieb am 11/22/2009:
Warum hast du nicht die generische Form von IEnumerable genommen? Die bietet auch ToArray. Ausserdem kann ich keinen Sinn darin erkennen, wenn man einen Referenztyp (zahlen) an einen anderen (list) übergibt. Beide zeigen auf den gleichen Heap. Änderst du in einem etwas, passiert das Gleiche in dem anderen.
Christopher Kk schrieb am 11/22/2009:
Hmm ganz ehrlich find ich das nicht so gut. Alleine was bei der ersten Version für Boxing Operationen passieren. Und warum sollte ich eine nichtgenerische Version einer generischen Version vorziehen wo ich jegliche Typsicherheit habe?
Marcel Kloubert schrieb am 11/22/2009:
@Rainer: Das stimmt nicht ganz: Ein allgemeines IEnumerable-Objekt hat ausschliesslich die Methode GetEnumerator(), das ein IEnumerator-Objekt zurückgibt womit du nur die Möglichkeiten hast, gemäß Iterator-Entwurfsmuster, an den Anfang zu springen und zum nächsten Objekt zu gehen. Sonst hätten Collections, wie ToolStripCollection bereits eine ToArray()-Methode. Du verwechselst das vielleicht mit List&lt;Tgt; oder ArrayList.

@Christopher: Es kann aus irgendwelchen Gründen immer mal vorkommen, dass Du ein Objekt bekommst das nur IEnumerable ist bzw. Du möchtest alle ToolStripCollection-Elemente als Array haben ohne selbst die Liste mit einem for oder foreach zu durchlaufen.

Gut, vielleicht ist der Beispielcode nicht der anschaulichste ;-)
Marcel Kloubert schrieb am 11/22/2009:
Korrektur:

es sollte heissen: "... Du möchtest alle ToolStripCollection-Elemente als Array haben ohne selbst die Liste mit einem foreach zu durchlaufen. ..."
Christopher Kk schrieb am 11/22/2009:
Gut ok das kann ja sein. Aber mir ist noch nicht so klar gewurden was ich für vorteile davon trage etwas in ein Array umzuwandeln wenn ich es doch als Collection vorliegen habe? Der Fall tritt ehrlich gesagt bei mir nicht so oft ein das ich das machen muss, eher andersum.
Rainer Hilmer schrieb am 11/23/2009:
@Marcel Kloubert: http://msdn.microsoft.com/en-us/library/bb298736.aspx
 

Logge dich ein, um hier zu kommentieren!