Wie initialisiere ich ein leeres Array in C #?

327

Ist es möglich, ein leeres Array ohne Angabe der Größe zu erstellen?

Zum Beispiel habe ich erstellt:

String[] a = new String[5];

Können wir das obige String-Array ohne die Größe erstellen?

Yogesh
quelle
2
stackoverflow.com/questions/151936/… u überprüfen Sie diesen Link, es kann Ihnen helfen, Array-Dinge klar zu verstehen
Ravi Gadag
2
Siehe auch alle möglichen C-
Sharp

Antworten:

434

Wenn Sie eine Sammlung verwenden, deren Größe Sie nicht im Voraus kennen, gibt es bessere Optionen als Arrays.

Verwenden Sie List<string>stattdessen ein - Sie können so viele Elemente hinzufügen, wie Sie benötigen. Wenn Sie ein Array zurückgeben müssen, rufen Sie ToArray()die Variable auf.

var listOfStrings = new List<string>();

// do stuff...

string[] arrayOfStrings = listOfStrings.ToArray();

Wenn Sie ein leeres Array erstellen müssen , können Sie dies tun:

string[] emptyStringArray = new string[0]; 
Oded
quelle
1
@Oded - string [] emptyStringArray = neuer String [0]; führt nicht zu einem leeren Array, oder? Es sieht so aus, als wäre es ein Array mit einem Element, bei dem dieses Element null ist.
Rory.ap
11
@roryap - Nein. Es ergibt sich ein string[], das keine Elemente hat. Wenn Sie versuchen, darauf zuzugreifen emptyStringArray[0], erhalten Sie eineIndexOutOfRangeException
Oded
@Oded - Danke, ich bin ziemlich neu in C #. In VB ist der bereitgestellte Index die Obergrenze und nicht die Anzahl der Elemente.
Rory.ap
1
Was würden Sie besser in Betracht ziehen: var strings = new string [] {}; oder var strings = neuer String [0]; Übrigens: Ich betrachte ein leeres Array als einen vollkommen gültigen Standard für Methodenparameter: public void EditItems (IEnumerable <Item> toEdit, IEnumerable <long> toDelete = new long [] {})
realbart
6
@ RickO'Shea - C ++ ist nicht C #. Stroustrup kennt sein C ++ - nicht so sicher, ob er sein C # und den .NET GC kennt. Ich werde nicht mit dir in einen religiösen Krieg gehen.
Oded
181

Versuche dies:

string[] a = new string[] { };
Hemant
quelle
7
Wenn Sie diese Antwort erweitern, können Sie das Array auch mit Elementen initiieren, ohne die Größe ODER den Typ anzugeben. Der Compiler leitet daraus entweder aus dem Initialisierer ab: var a = new [] {"a", "b", "c"}; Dies ist immer noch ein stark typisiertes String-Array.
Nick VanderPyle
1
Nicht behandelte Ausnahme: System.IndexOutOfRangeException: Der Index befand sich außerhalb der Grenzen des Arrays. at ArrayClass.Main (String [] args). Ich habe diesen Fehler
festgestellt,
6
@ Yogesh: Das ist seltsam. Wenn Sie es beispielsweise schreiben int[] variable = new int[]{}und verwenden, zum Beispiel in einer Schleife, wie foreach (var s in variable){ Console.WriteLine(s);}der Code, wird kompiliert zu: int[] args1 = new int[0];und foreach (int num in args1){Console.WriteLine(num);}. Es sollte also keinen Unterschied zwischen der Verwendung von new int[0]und geben, new int[]{}da beide mit demselben Code kompiliert werden.
Nein,
1
@GlennGordon Absolut, aber das ist neu ab C # Version 3.0 (ab 2007 mit Visual Studio 2008). Diese Version erlaubt auch ein anderes einfaches Format mit var, allerdings nur für lokale Variablen (nicht für Felder). In C # 2.0 (Visual Studio 2005) und früheren Versionen mussten Sie jedoch die Syntax dieser Antwort (oder string[] a = new string[0];) verwenden.
Jeppe Stig Nielsen
113

In .NET 4.6 wird bevorzugt eine neue Methode verwendet Array.Empty:

String[] a = Array.Empty<string>();

Die Implementierung ist prägnant und verwendet das Verhalten statischer Elemente in generischen Klassen in .Net :

public static T[] Empty<T>()
{
    return EmptyArray<T>.Value;
}

// Useful in number of places that return an empty byte array to avoid
// unnecessary memory allocation.
internal static class EmptyArray<T>
{
    public static readonly T[] Value = new T[0];
}

(Code vertragsbezogener Code aus Gründen der Übersichtlichkeit entfernt)

Siehe auch:

Kobi
quelle
@ Cole Johnson - Danke für die Bearbeitung, aber ich habe sie zurückgesetzt. Ich habe diese Zeilen absichtlich weggelassen: Ich wollte nur die interessante Implementierung zitieren. Der Codevertrag und die Attribute behindern nur das Verständnis, was passiert (der Link zur Quelle enthält natürlich alles). Ich habe dem Kommentar auch eine neue Zeile hinzugefügt, um ein Scrollen im Stapelüberlauf zu vermeiden. Wenn es Ihnen nichts ausmacht, bevorzuge ich es so. Vielen Dank!
Kobi
2
Auf jeden Fall eine Verbesserung für die Lesbarkeit von:Enumerable.Empty<T>().ToArray()
DanielV
Obwohl diese Methode in den meisten Fällen definitiv bevorzugt wird, beantwortet sie nicht die ursprüngliche Frage. Das OP möchte ein leeres Array erstellen . Array.Empty<T>()ist nicht ein Array erstellen. Es gibt einen Verweis auf ein vorab zugewiesenes Array zurück.
13.
33

Sie können es mit einer Größe von 0 initialisieren, müssen es jedoch neu initialisieren, wenn Sie die Größe kennen, da Sie es nicht an das Array anhängen können.

string[] a = new string[0];
MatthiasG
quelle
Dies ist die genaue Antwort
Abzarak
7

Es macht nicht viel Sinn, ein Array ohne Größe zu deklarieren. Ein Array hat ungefähr die Größe . Wenn Sie ein Array mit einer bestimmten Größe deklarieren, geben Sie die feste Anzahl von Slots an, die in einer Sammlung verfügbar sind, die Dinge aufnehmen können, und dementsprechend wird Speicher zugewiesen. Um etwas hinzuzufügen, müssen Sie das vorhandene Array trotzdem neu initialisieren (auch wenn Sie die Größe des Arrays ändern, siehe diesen Thread ). Einer der seltenen Fälle, in denen Sie ein leeres Array initialisieren möchten, besteht darin, das Array als Argument zu übergeben.

Wenn Sie eine Sammlung definieren möchten, wenn Sie nicht wissen, welche Größe sie möglicherweise haben könnte, ist das Array nicht Ihre Wahl, sondern so etwas wie ein List<T>oder ähnliches.

Die einzige Möglichkeit, ein Array ohne Angabe der Größe zu deklarieren, besteht darin, ein leeres Array der Größe 0 zu haben . Hemant und Alex Dn bieten zwei Möglichkeiten. Eine andere einfachere Alternative ist einfach :

string[] a = { };

[ Die Elemente in der Klammer sollten implizit in den definierten Typ konvertierbar sein, z. B.string[] a = { "a", "b" }; ]

Oder noch eine andere:

var a = Enumerable.Empty<string>().ToArray();

Hier ist ein deklarativerer Weg :

public static class Array<T>
{
    public static T[] Empty()
    {
        return Empty(0);
    }

    public static T[] Empty(int size)
    {
        return new T[size];
    }
}

Jetzt können Sie anrufen:

var a = Array<string>.Empty();

//or

var a = Array<string>.Empty(5);
nawfal
quelle
1
Ich kann mir keine Verwendung vorstellen, außer wenn Sie ein Array als Parameter übergeben müssen. Es gibt einige Fälle in der Reflexion, in denen eine Methode ein Array von Objekten akzeptiert und Sie möglicherweise ein leeres Array übergeben möchten, um die Standardaktion auszuführen. Ich werde meine Antwort bearbeiten.
Nawfal
Sie haben beispielsweise eine Schnittstelle, die von mehreren Klassen implementiert wurde, die eine IEnumerable zurückgeben, und eine der Implementierungen enthält keine Elemente für die Methode und gibt beispielsweise ein leeres Array zurück.
Ignacio Soler Garcia
@IgnacioSolerGarcia Ich würde in diesem Fall genau dann ein Array zurückgeben, wenn es sich um eine äußerst leistungskritische Anwendung handelt. Ich werde sagen, Arrays sind veraltet und sollten vermieden werden, wenn Sie können. Sehen Sie dies von Lippert und diese SO-Frage
nawfal
Beachten Sie, dass der zurückgegebene Typ IEnumerable ist, sodass das Array schreibgeschützt ist und sich nicht ändern soll. Warum sollte ich in diesem Fall beispielsweise eine Liste zurückgeben?
Ignacio Soler Garcia
1
Ein Anwendungsfall für ein leeres Array ist einfach - wenn Sie es mit Objekten füllen möchten und nicht wissen, wie viele Sie hinzufügen werden!
Vapcguy
6

Einfach und elegant!

string[] array = {}
disklosr
quelle
Ich würde arrayeinfach ändern a, wie arrayes ein Schlüsselwort ist, wenn es groß geschrieben wird. Es ist nur eine schlechte Praxis, einen Schlüsselwortnamen als Variablennamen zu verwenden - auch wenn der Fall anders ist. Und im Grunde das gleiche wie meine Antwort, außer dass ich dort String.Emptydrin war.
Vapcguy
1
1. Array ist kein Schlüsselwort ac #. Array ist eine Klasse und kein Schlüsselwort 2. "a" ist auch eine schlechte Praxis (vielleicht noch schlimmer eine schlechte Praxis als die Verwendung von Schlüsselwörtern)
disklosr
Technisch sein. Klasse, Schlüsselwort, definiert einen Objekttyp und ist immer noch schlecht. Warum denkst du aist schlecht?
Vapcguy
1
Weil nicht beschreibende und aus einem Buchstaben bestehende Variablennamen eine schlechte Praxis sind, weil sie nicht den Grund für ihre Definition angeben. "Array" ist sicherlich ein besserer Name als "a". Ein besserer Name wäre "emptyArray".
Disklosr
4

string[] a = new string[0];

oder kurze Notation:

string[] a = { };

Der bevorzugte Weg ist jetzt:

var a = Array.Empty<string>();

Ich habe einen kurzen regulären Ausdruck geschrieben, den Sie in Visual Studio verwenden können, wenn Sie Zuordnungen mit der Länge Null ersetzen möchten, z new string[0]. Verwenden Sie Suchen (Suchen) in Visual Studio mit aktivierter Option für reguläre Ausdrücke:

new[ ][a-zA-Z0-9]+\[0\]

Jetzt Find All oder F3 (Find Next) und ersetze alle durch Array.Empty <…> ()!

juFo
quelle
3

Sie können die Arraygröße zur Laufzeit definieren .

Auf diese Weise können Sie alles tun, um die Größe des Arrays dynamisch zu berechnen. Einmal definiert, ist die Größe jedoch unveränderlich.

Array a = Array.CreateInstance(typeof(string), 5);
Radarbob
quelle
4
Warum das alles? Zur Laufzeit können Sie die Array-Größe normalerweise aus einer Variablen definieren:int i = 5; string[] a = new string[i];
Kevin Brock
Nun, ich denke mit Generika scheint dies veraltet zu sein.
Radarbob
2

Ich hatte versucht:

string[] sample = new string[0];

Aber ich konnte nur eine Zeichenfolge einfügen, und dann bekam ich einen exceptionOutOfBound-Fehler, also habe ich einfach eine Größe dafür eingefügt, wie z

string[] sample = new string[100];

Oder eine andere Art und Weise, die für mich funktioniert:

List<string> sample = new List<string>();

Wert für Liste zuweisen:

sample.Add(your input);
Cs_Lu
quelle
1

Wie ich weiß, können Sie kein Array ohne Größe erstellen, aber Sie können es verwenden

List<string> l = new List<string>() 

und dann l.ToArray().

Alex Dn
quelle
1

Kombinieren von @ nawfal & @ Kobi-Vorschlägen:

namespace Extensions
{
    /// <summary> Useful in number of places that return an empty byte array to avoid unnecessary memory allocation. </summary>
    public static class Array<T>
    {
        public static readonly T[] Empty = new T[0];
    }
}

Anwendungsbeispiel:

Array<string>.Empty

UPDATE 2019-05-14

(Dank an @Jaider ty)

Bessere Verwendung der .Net-API:

public static T[] Empty<T> ();

https://docs.microsoft.com/en-us/dotnet/api/system.array.empty?view=netframework-4.8

Gilt für:

.NET Core: 3.0 Vorschau 5 2.2 2.1 2.0 1.1 1.0

.NET Framework: 4.8 4.7.2 4.7.1 4.7 4.6.2 4.6.1 4.6

.NET Standard: 2.1 Vorschau 2.0 1.6 1.5 1.4 1.3

...

HTH

ShloEmi
quelle
1
In .NET Core 2 gibt es bereits eine Erweiterung dafürarr = Array.Empty<string>();
Jaider
iirc, in .NetStandart [4.something] - gibt es auch.
ShloEmi
0

Du kannst tun:

string[] a = { String.Empty };

Hinweis: OP bedeutete, keine Größe angeben zu müssen und ein Array nicht größenlos zu machen

vapcguy
quelle
7
Wird dadurch kein String-Array mit der Länge 1 erstellt?
Sumner Evans
Stimmt, aber es ist geklärt. Und OP hat darum gebeten, das Array zu deklarieren, ohne eine Größe angeben zu müssen - das passt dazu.
Vapcguy
Und das verdient eine Ablehnung, warum? OP bedeutete, keine specifyGröße zu haben, kein Array zu erstellen sizeless.
Vapcguy
1
@ vapcguy Ich war der Downvoter. Ich bereue es. Ich habe Ihre Antwort bearbeitet, um meine Ablehnung abzubrechen. Ihr Kommentar macht die Frage etwas zweifelhaft. Ich bin mir nicht sicher, ob OP das bedeutet.
Nawfal
4
Das OP bat um ein leeres Array. Dieses Array ist nicht leer.
Keith
0

Hier ist ein Beispiel aus der Praxis. In diesem Fall muss das Array foundFileszuerst auf die Länge Null initialisiert werden .

(Wie in anderen Antworten hervorgehoben: Dies initialisiert kein Element und insbesondere kein Element mit dem Index Null, da dies bedeuten würde, dass das Array die Länge 1 hat. Das Array hat nach dieser Zeile die Länge Null!).

Wenn das Teil = string[0]weggelassen wird, liegt ein Compilerfehler vor!

Dies liegt am Fangblock ohne erneutes Werfen. Der C # -Compiler erkennt den Codepfad, dass die Funktion Directory.GetFiles()eine Ausnahme auslösen kann, sodass das Array nicht initialisiert werden kann.

Bevor jemand sagt, die Ausnahme nicht erneut auszulösen, wäre eine schlechte Fehlerbehandlung: Dies ist nicht wahr. Die Fehlerbehandlung muss den Anforderungen entsprechen.

In diesem Fall wird davon ausgegangen, dass das Programm im Falle eines nicht lesbaren Verzeichnisses fortgesetzt und nicht unterbrochen werden soll. Das beste Beispiel ist eine Funktion, die eine Verzeichnisstruktur durchläuft. Hier protokolliert die Fehlerbehandlung sie nur. Dies könnte natürlich besser gemacht werden, z. B. das Sammeln aller Verzeichnisse mit fehlgeschlagenen GetFiles(Dir)Aufrufen in einer Liste, aber dies wird hier zu weit führen.

Es genügt zu sagen, dass das Vermeiden throwein gültiges Szenario ist, und daher muss das Array auf die Länge Null initialisiert werden. Es würde ausreichen, dies im Catch-Block zu tun, aber das wäre ein schlechter Stil.

Der Aufruf zum GetFiles(Dir)Ändern der Größe des Arrays.

string[] foundFiles= new string[0];
string dir = @"c:\";
try
{
    foundFiles = Directory.GetFiles(dir);  // Remark; Array is resized from length zero
}
// Please add appropriate Exception handling yourself
catch (IOException)
{
  Console.WriteLine("Log: Warning! IOException while reading directory: " + dir);
  // throw; // This would throw Exception to caller and avoid compiler error
}

foreach (string filename in foundFiles)
    Console.WriteLine("Filename: " + filename);
Philm
quelle