Frage

public class Sample
{
     static int count = 0;
     public int abc;
     public Sample()
     {
        abc = ++Sample.count;
     }
}

Ich möchte ein Array der obigen Klasse erstellen und möchte, dass jedes Element im Array durch Aufrufen des Standardkonstruktors initialisiert wird, damit jedes Element unterschiedlich sein kann abcSo habe ich das gemacht:

Sample[] samples = new Sample[100];

Aber das tut nicht das, was ich denke, es sollte es tun. Auf diese Weise wird der Standardkonstruktor nicht aufgerufen. Wie kann ich beim Erstellen eines Arrays einen Standardkonstruktor aufrufen?

Ich möchte auch wissen, was die obige Aussage tut?

War es hilfreich?

Lösung

Sie können im Grunde genommen nicht. Wenn Sie ein Array erstellen, ist es immer zunächst mit dem Standardwert für den Typ besiedelt - was für eine Klasse immer eine Nullreferenz ist. Zum int Es ist 0, für bool Es ist falsch usw.

(Wenn Sie einen Array -Initialisierer verwenden, wird das "leere" Array und erstellt dann Populieren Sie es natürlich mit den Werten, die Sie angegeben haben.)

Es gibt verschiedene Möglichkeiten, das Array zu bevölkern, indem Sie den Konstruktor aufrufen - ich würde wahrscheinlich Verwenden Sie einfach eine Foreach -Schleife. Verwenden von LINQ mit aufzählbar.Range/Wiederholung fühlt sich ein wenig erzwungen an.

Natürlich könntest du immer schreiben Ihre eigene Bevölkerungsmethode, auch als Erweiterungsmethode:

public static T[] Populate<T>(this T[] array, Func<T> provider)
{
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = provider();
    }
    return array;
}

Dann könnten Sie verwenden:

Sample[] samples = new Sample[100].Populate(() => new Sample());

Was ich an dieser Lösung mag:

  • Es ist immer noch ein einziger Ausdruck, der in verschiedenen Szenarien nützlich sein kann
  • Es werden keine Konzepte eingeführt, die Sie nicht wollen (wie das Wiederholen eines einzelnen Wertes oder das Erstellen eines Bereichs)

Natürlich können Sie weitere Optionen hinzufügen:

  • Eine Überlastung, die eine erfordert Func<int, T> anstelle einer Func<T>, den Index an den Anbieter weitergeben
  • Eine Nichtverwalter-Methode, die das Array erstellt und bevölkert es

Andere Tipps

Ihr Code erstellt nur das Array, aber keiner seiner Gegenstände. Grundsätzlich müssen Sie Instanzen speichern von Sample hinein Dieses Array.

Um es einfach auszudrücken, ohne schicke Linq usw.:

Sample[] samples = new Sample[100];
for (int i = 0; i < samples.Length; i++) samples[i] = new Sample();

Bitte beachten Sie auch, dass Ihre Lösung ist nicht Thread-safe.

Es gibt keine Möglichkeit, dies automatisch zu tun. Die Array -Initialisierung wird im Wesentlichen "diesen Speicherblock auf 0s löschen". Sie müssten so etwas tun wie:

var arr = new SomeType[size];
for(int i = 0 ; i < size ; i++) arr[i] = new SomeType();

An diesem Punkt haben Sie eine leere Auswahl an Größe 100, wenn Sie es mit Gegenständen füllen möchten, müssten Sie so etwas tun wie:

for(int i=0; i<samples.Length; i++) {
   samples[i] = new Sample();
}

Das Problem ist, dass Sie durch die Erklärung dieses Arrays nie Platz für jedes Objekt zugewiesen haben. Sie haben lediglich Platz für 100 Objekte vom Typ Probe zugewiesen. Sie müssen den Konstruktor auf jeden selbst anrufen.

Erkenntnissen:

Food[] foods = Food[100];
for (int k = 0; k < foods.length; k++) {
   foods[k] = new Food();
}

Eine interessante Arbeit könnte eine Fabrikfunktion sein. Erwägen Sie dies an Ihre Beispielklasse.

public static Sample[] getInstances(int aNumber) {
    Sample[] sample = Sample[aNumber];
    for (int k = 0; k < sample.length; k++) {
       sample[k] = new Sample();
    }

    return sample;
}

Versteckt den Makel ein wenig - sofern dies eine nützliche Funktion für Sie ist.

Hier ist ein anderer Ein-Liner, für den keine Erweiterungsmethode erforderlich ist:

Sample[] array = Enumerable.Range(0, 100).Select(i => new Sample()).ToArray();

Eine weitere schöne Option ist Scotts Vorschlag zu Jons Antwort:

public static T[] Populate<T>(this T[] array) 
    where T : new()
{
    for (int i = 0; i < array.Length; i++)
        array[i] = new T();
    return array;
}

So können Sie:

Sample[] array = new Sample[100].Populate();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top