Beste Möglichkeit, IList oder IEnumerable in Array zu konvertieren

98

Ich habe eine HQL-Abfrage, die entweder eine IList von Ergebnissen oder eine IEnumerable von Ergebnissen generieren kann.

Ich möchte jedoch, dass ein Array der von mir ausgewählten Entität zurückgegeben wird. Wie kann dies am besten erreicht werden? Ich kann entweder durchzählen und das Array erstellen oder CopyTo () als definiertes Array verwenden.

Gibt es einen besseren Weg? Ich habe mich für den CopyTo-Ansatz entschieden.

Jishi
quelle
4
Hat jemand eine Lösung ohne Linq?
Bitterblue

Antworten:

166

Welche .NET-Version verwenden Sie? Wenn es sich um .NET 3.5 handelt, würde ich einfach anrufen ToArray()und damit fertig sein.

Wenn Sie nur eine nicht generische IEnumerable haben, gehen Sie wie folgt vor:

IEnumerable query = ...;
MyEntityType[] array = query.Cast<MyEntityType>().ToArray();

Wenn Sie den Typ in dieser Methode nicht kennen, die Aufrufer der Methode ihn jedoch kennen, machen Sie die Methode generisch und versuchen Sie Folgendes:

public static void T[] PerformQuery<T>()
{
    IEnumerable query = ...;
    T[] array = query.Cast<T>().ToArray();
    return array;
}
Jon Skeet
quelle
Es ist 3.5, aber die IQuery hat weder ein ToArray noch IEnumerable oder IList, soweit ich das beurteilen kann?
Jishi
2
Nein - es gibt nur eine Erweiterungsmethode. (Es ist nicht in der Schnittstelle selbst.)
Jon Skeet
3
@Shimmy: Ja, es gibt ... abgesehen von allem anderen sagt es dem Compiler, welche Art von Array zu erwarten ist! Wenn Sie nur eine object[]gerechte Verwendung wünschen Cast<object>. Das Nongeneric IEnumerablehat keine ToArrayErweiterungsmethode, Sie können also nicht einfach aufrufen foo.ToArray<object>oder ähnliches.
Jon Skeet
22
Die ToArrayErweiterungsmethode befindet sich im System.LinqNamespace, dachte, das wäre gut zu wissen :).
Tomas Jansson
1
@Alexander: Nicht , wenn der Wert , die zurückgegeben wirklich ist eine entsprechende Anordnung.
Jon Skeet
47

Fügen Sie Folgendes in Ihre CS-Datei ein:

using System.Linq;

Sie können dann die folgende Erweiterungsmethode aus System.Linq.Enumerable verwenden:

public static TSource[] ToArray<TSource>(this System.Collections.Generic.IEnumerable<TSource> source)

Dh

IEnumerable<object> query = ...;
object[] bob = query.ToArray();
Michael Joyce
quelle
ahh ... das Unit-Test-Projekt enthält standardmäßig nicht die Linq. Danke dir!
zsf222
6

Ich möchte das Rad neu erfinden ...

public static T[] ConvertToArray<T>(this IEnumerable<T> enumerable)
{
    if (enumerable == null)
        throw new ArgumentNullException("enumerable");

    return enumerable as T[] ?? enumerable.ToArray();
}
Philippe Matray
quelle
Können Sie Ihre Antwort erklären und auch, was Sie damit meinen, dass Sie das Rad neu erfinden?
ChrisCamp
heh - Ich mag das eigentlich so: In der Off-Chance, dass die Aufzählung tatsächlich ein Array ist, überspringen Sie die neue Zuordnung / Kopie zu Schritten im ToArray()Aufruf (über die interne BufferKlasse) ... obwohl, wenn jemand den "Standard" erwartet hat "Kopierverhalten, sie wären ziemlich überrascht.
JerKimball
@ Chris: Weil ich von der Signatur der ToArray () -Methode in System.Linq inspiriert wurde. msdn.microsoft.com/en-us/library/bb298736.aspx
Philippe Matray
Für zusätzliche Lächerlichkeit sollte die Implementierung dieser MethodeIEnumerable.ToArray()
The Muffin Man
2

Falls Sie Linq nicht haben, habe ich es folgendermaßen gelöst:

    private T[] GetArray<T>(IList<T> iList) where T: new()
    {
        var result = new T[iList.Count];

        iList.CopyTo(result, 0);

        return result;
    }

Ich hoffe es hilft

Schleppen
quelle