Инициализация массива с помощью конструктора по умолчанию
public class Sample
{
static int count = 0;
public int abc;
public Sample()
{
abc = ++Sample.count;
}
}
Я хочу создать массив вышеуказанного класса и хочу, чтобы каждый элемент в массиве был инициализирован путем вызова конструктора по умолчанию, чтобы каждый элемент мог иметь разные abc
.Так я и сделал:
Sample[] samples = new Sample[100];
но это не делать то, что я думаю, что он должен делать. Похоже, таким образом, конструктор по умолчанию не вызывается. Как вызвать конструктор по умолчанию при создании массива?
Я также хотел бы знать, что делает вышеуказанное заявление делать?
6 ответов
вы не можете, в принципе. При создании массива он всегда изначально заполняется значением по умолчанию для типа, которое для класса всегда является нулевой ссылкой. Для int
0, то для bool
- Это ложь и т. д.
(если вы используете инициализатор массива, что создаст пустой массив и затем заполните его значениями, которые вы указали, конечно.)
существуют различные способы заполнения массива путем вызова конструктора - я бы наверное просто используйте цикл foreach сам. Использование LINQ с Перечислимым.Диапазон / повтор чувствует себя немного вынужденным.
конечно, вы всегда можете написать ваш собственный метод народонаселения, даже как метод расширения:
public static T[] Populate<T>(this T[] array, Func<T> provider)
{
for (int i = 0; i < array.Length; i++)
{
array[i] = provider();
}
return array;
}
затем вы можете использовать:
Sample[] samples = new Sample[100].Populate(() => new Sample());
что мне нравится в этом решении:
- это еще одно выражение, которое может быть полезно в различных ситуациях
- это не вводит понятия, которые вы на самом деле не хотите (например, повторение одного значения или создание диапазона)
конечно, вы можете добавить больше опций:
- перегрузка, которая принимает
Func<int, T>
вместоFunc<T>
, передавая индекс поставщику - метод без расширения, который создает массив и заполняет ее
ваш код создает только массив, но ни один из ее элементов. В принципе, вам нужно хранить экземпляры of Sample
на этот массив.
проще говоря, без каких-либо фантазии LINQ и т. д.:
Sample[] samples = new Sample[100];
for (int i = 0; i < samples.Length; i++) samples[i] = new Sample();
Пожалуйста, обратите внимание, что ваше решение не потокобезопасным.
нет способа сделать это автоматически; инициализация массива по существу "стереть этот блок памяти до 0s". Вам придется сделать что-то вроде:
var arr = new SomeType[size];
for(int i = 0 ; i < size ; i++) arr[i] = new SomeType();
на данный момент у вас есть пустой массив размером 100, если вы хотите заполнить его элементами, то вам нужно будет сделать что-то вроде:
for(int i=0; i<samples.Length; i++) {
samples[i] = new Sample();
}
проблема в том, что, объявив этот массив, вы никогда не выделяли пространство для каждого объекта. Вы просто выделили место для 100 объектов типа Sample. Вам придется вызвать конструктор на каждом из них самостоятельно.
разработка:
Food[] foods = Food[100];
for (int k = 0; k < foods.length; k++) {
foods[k] = new Food();
}
интересная работа вокруг может быть фабричной функцией. Рассмотрим прикрепление к образец класса.
public static Sample[] getInstances(int aNumber) {
Sample[] sample = Sample[aNumber];
for (int k = 0; k < sample.length; k++) {
sample[k] = new Sample();
}
return sample;
}
скрывает пятно, немного-при условии, что это полезная функция для вас.
вот еще один однострочный, который не требует какого-либо метода расширения:
Sample[] array = Enumerable.Range(0, 100).Select(i => new Sample()).ToArray();
еще один хороший вариант-это Скотта предложение to Джон:
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;
}
Так что вы можете сделать:
Sample[] array = new Sample[100].Populate();