Domanda

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

Voglio creare un array di classe superiore, e desidera che ogni elemento della matrice da inizializzare invocando il costruttore di default, in modo che ogni elemento può avere diversi abc.So ho fatto questo:

Sample[] samples = new Sample[100];

Ma questo non fa quello che penso che dovrebbe fare. Sembra che in questo modo il costruttore di default non è sempre chiamato. Come richiamare costruttore di default quando si crea un array?

Mi piacerebbe anche sapere che cosa fa la dichiarazione di cui sopra?

È stato utile?

Soluzione

Non è possibile, in fondo. Quando si crea un array, è sempre inizialmente popolato con il valore di default per il tipo - che per una classe è sempre un riferimento null. Per int è 0, per bool è falso, ecc.

(Se si usa un inizializzatore matrice, che creerà il "vuoto" matrice e poi popolarlo con i valori che hai specificato, naturalmente.)

Ci sono vari modi di popolamento della matrice chiamando il costruttore - mi sarebbe probabilmente basta usare un ciclo foreach me stesso. Utilizzando LINQ con Enumerable.Range / Repeat sente un po 'forzata.

Naturalmente, si può sempre di scrittura il proprio metodo di popolazione, anche come un metodo di estensione:

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

Allora si potrebbe usare:

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

Quello che mi piace di questa soluzione:

  • E 'ancora una sola espressione, che può essere utile in diversi scenari
  • Non ha introdurre concetti in realtà non desiderate (come la ripetizione di un singolo valore o la creazione di una serie)

Naturalmente si potrebbe aggiungere ulteriori opzioni:

  • Un sovraccarico che prende un Func<int, T> invece di un Func<T>, passando l'indice al provider
  • Un metodo non estensione che crea l'array e popola

Altri suggerimenti

Il codice crea solo il array , ma nessuno dei suoi elementi. In sostanza, è necessario memorizzare istanze di Sample in questo array.

Per dirla semplice, senza alcuna fantasia LINQ, ecc.

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

Si prega di notare anche la soluzione è non thread-safe.

Non c'è modo per farlo automaticamente; inizializzazione array è essenzialmente "cancellare questo blocco di memoria 0s". Si dovrebbe fare qualcosa di simile:

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

A questo punto si dispone di una matrice vuota di dimensione 100, se si desidera riempire con oggetti, allora si dovrebbe fare qualcosa di simile:

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

Il problema è che, dichiarando tale matrice, non hai mai assegnato lo spazio per ogni oggetto. È semplicemente assegnato lo spazio per 100 oggetti di tipo Sample. Dovrete chiamare il costruttore su ogni te stesso.

Per approfondire:

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

Un lavoro interessante intorno potrebbe essere una funzione di fabbrica. Considerate questo allegando alla classe di esempio.

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

    return sample;
}

Nasconde la macchia, un po '-. Fornisce questa è una funzione utile a voi

Ecco un altro uno-liner che non richiede alcun metodo di estensione:

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

Un'altra opzione interessante è il suggerimento di Scott per di Jon risposta :

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;
}

Così si può fare:

Sample[] array = new Sample[100].Populate();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top