Pregunta

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

Quiero crear una matriz de la clase anterior y quiero que cada elemento en la matriz se inicialice invocando el constructor predeterminado, para que cada elemento pueda tener diferente abc.As hice esto:

Sample[] samples = new Sample[100];

Pero esto no hace lo que creo que debería hacer. Parece que no se llama el constructor predeterminado. ¿Cómo invocar el constructor predeterminado al crear una matriz?

También me gustaría saber qué hace la declaración anterior.

¿Fue útil?

Solución

No puedes, básicamente. Cuando crea una matriz, siempre está inicialmente poblada con el valor predeterminado para el tipo, que para una clase siempre es una referencia nula. Para int es 0, para bool es falso, etc.

(Si usa un inicializador de matriz, eso creará la matriz "vacía" y después Ulérate con los valores que has especificado, por supuesto).

Hay varias formas de poblar la matriz llamando al constructor, lo haría probablemente Simplemente use un bucle foreach yo mismo. Usar Linq con enumerable. Range/Repetir se siente un poco forzado.

Por supuesto que siempre puedes escribe Su propio método de población, incluso como método de extensión:

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

Entonces podrías usar:

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

Lo que me gusta de esta solución:

  • Sigue siendo una sola expresión, que puede ser útil en varios escenarios.
  • No introduce conceptos que realmente no desea (como repetir un solo valor o crear un rango)

Por supuesto que podría agregar más opciones:

  • Una sobrecarga que toma un Func<int, T> en lugar de un Func<T>, pasando el índice al proveedor
  • Un método que no es de extensión que crea la matriz y lo poca

Otros consejos

Tu código crea solo el formación, pero ninguno de sus artículos. Básicamente, necesitas instancias de almacenamiento de Sample dentro esta matriz.

Para decirlo simple, sin ningún Linq elegante, etc.:

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

Tenga en cuenta también que su solución es no a salvo de amenazas.

No hay forma de hacerlo automáticamente; La inicialización de la matriz es esencialmente "borrar este bloque de memoria a 0s". Tendrías que hacer algo como:

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

En este punto, tiene una matriz vacía de talla 100, si desea llenarlo con artículos, entonces tendrá que hacer algo como:

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

El problema es que al declarar esa matriz, nunca asignó espacio para cada objeto. Simplemente asignó espacio para 100 objetos de muestra de tipo. Tendrás que llamar al constructor en cada uno tú mismo.

Elaborar:

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

Un trabajo interesante podría ser una función de fábrica. Considere adjuntar esto a su clase de muestra.

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

    return sample;
}

Oculta la mancha, un poco, siempre que esta sea una función útil para usted.

Aquí hay otra línea de una sola que no requiere ningún método de extensión:

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

Otra buena opción es Sugerencia de Scott a La respuesta de Jon:

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

Para que puedas hacer:

Sample[] array = new Sample[100].Populate();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top