Я наткнулся на неожиданное поведение в C#. Может ли массив неявно изменить свой размер?

Я новичок в программировании и только начал изучать C#, поэтому просто базовые упражнения. Я пытался просто заполнить массив случайными значениями и получить наибольшее число и количество повторений. Я использую .NET 8.0, C# 12.

using static System.Random;

uint[] numberList = new uint[8];
WriteLine(numberList.Length);
/*
for (uint i = 0; i < numberList.Length;i++) {
numberList[i] = (uint)new Random().Next(0,9);
}
*/
numberList = [1,1,1,2,3,8,8,7,10,10,11];
WriteLine(numberList.Length);
uint[] biggerNum = [0,0];

for (uint i = 0; i < numberList.Length; i++){
    if (numberList[i] > biggerNum[0]) {
        biggerNum[0] = numberList[i];
    }
    WriteLine("Value of i: " + i);
    WriteLine("Value in the array: " + numberList[i]);
}

for (uint i = 0; i < numberList.Length; i++) {
    if (numberList[i] == biggerNum[0]) biggerNum[1]++;
}

WriteLine(format:"The number: {0} \nRepeated: {1} times.",
            arg0:biggerNum[0],
            arg1:biggerNum[1]);

Пока я возился с ним, я объявил массив размером 10. Но после того, как я заполнил его 11 значениями, его размер просто изменился.

Я ожидал получить ошибку компиляции, но это сработало. Потом я подумал: «Может быть, компилятор просто распознал, что я использовал 11 значений, и изменил их размер при компиляции?» Но нет, запустив код, я увидел, что на самом деле он был объявлен с размером 10 и после

numberList = [1,1,1,2,3,8,8,7,10,10,11];

его размер только что был изменен до 11. Я пробовал использовать несколько значений, начиная с 8, 5, а затем назначая больше. Есть ли что-то, что мне не хватает? Я пытался использовать Gemini, чтобы узнать, следует ли изменить размер, но он продолжал говорить, что изменить размер массива невозможно, чего я и ожидал. Конкретно в документации этого не нашел. Я знаю, что мне следует объявить что-то вроде uint[] numberList = [1,1,1,2,3,8,8,7,10,10,11];, но это ведет себя так, будто я скрываю массив, хотя я просто присваиваю значение (я знаю, это глупый способ).

Его размер не изменился — вы заменили его ссылкой на совершенно новый массив.

Ry- 04.07.2024 02:11

И Близнецы в любом случае неправы если так сказали.

Ry- 04.07.2024 02:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
70
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

new uint[8];

Это создает новый массив из 8 элементов.

uint[] numberList = // ...

При этом создается ссылка на массив с именем numberList и присваивается ему объект, в данном случае массив из 8 элементов.

[1,1,1,2,3,8,8,7,10,10,11];

Это создает другой массив из 11 элементов.

numberList = // ...

Это заставляет numberList ссылаться на новый массив (с 11 элементами). На массив из 8 элементов больше нет ссылок.

о, это имеет смысл, я думал, что это похоже на инициализацию/заполнение массива. Если рассматривать это как ссылку, становится ясно. Что в этом случае происходит с первым массивом? идет на сбор мусора? следует ли мне воспринимать это как беспокойство по поводу производительности?

giurno B 04.07.2024 02:44

@giurnoB Теперь первый массив можно будет бесплатно собирать мусором, да. Ваш пример программы сам по себе не имеет особого смысла, потому что он печатает размер первого массива, затем закомментированную часть, заполняющую этот массив, и затем вы переключаетесь на другой массив. Конечно, производительность будет выше, если вы просто удалите первые строки (до назначения второго массива), но я предполагаю, что в конечном итоге вам понадобится массив со случайными числами, поэтому ваш окончательный код все равно будет выглядеть иначе. (уточняется)

DevSolar 04.07.2024 18:18

К сожалению, как и в случае с Java, в попытке сделать C# «лучше», чем C++, они отказались от ясности того, что такое объект, а что — ссылка на объект. Ссылки, допускающие значение NULL, являются попыткой исправить эту проблему, но они не являются обязательными, существует множество устаревшего кода, который их не использует, и из них есть исключения, поэтому в целом в C# все гораздо сложнее в этом отношении. вместо «лучше». Основное правило заключается в том, что ссылку следует объявлять только там, где она может быть инициализирована.

DevSolar 04.07.2024 18:22
Ответ принят как подходящий

Размер массива не был изменен.

Вы объявили массив с именем numberList. Массивы являются ссылочными типами, и вы сделали их ссылкой на массив из 8 элементов. Затем вы назначили массив с большим количеством элементов, так что numberList теперь ссылается на больший массив.

Но исходный массив остался неизменным. А поскольку на него больше ничего не ссылается, теперь его может очистить сборщик мусора.

Другие вопросы по теме