Упражнение. Обнаружение ссылочных типов
- 8 мин
К ссылочным типам относятся массивы, классы и строки. Ссылочные типы обрабатываются по-разному от типов значений относительно способа хранения значений при выполнении приложения.
В этом упражнении вы узнаете, как ссылочные типы отличаются от типов значений и как использовать new оператор для связывания переменной со значением в памяти компьютера.
Отличие ссылочных типов от типов значений
Переменная типа значения хранит значения непосредственно в области хранилища, называемой стеком. Стек — это память, выделенная для кода, который выполняется центральным процессором в настоящее время (также называется кадром стека или кадром активации). Когда выполнение кадра стека завершается, значения в стеке удаляются.
Переменная ссылочного типа хранит значения в отдельном регионе памяти, называемом кучей. Куча — это область памяти, которая используется совместно приложениями, работающими в операционной системе одновременно. Среда выполнения .NET взаимодействует с операционной системой, чтобы определить доступные адреса памяти, и запрашивает адрес, по которому можно сохранить значение. Далее среда выполнения .NET сохраняет значение и возвращает адрес памяти переменной. Когда переменная используется в коде, среда выполнения .NET обращается по хранящемуся в переменной адресу и получает сохраненное значение.
Далее вы напишете код, иллюстрирующий эти идеи более четко.
Определение переменной ссылочного типа
Удалите или используйте оператор
//строковый комментарий, чтобы закомментировать весь код из предыдущих упражнений.Обновите код в редакторе Visual Studio Code следующим образом:
int[] data;Предыдущий код определяет переменную, которая может содержать значение массива типов
int.На этом этапе
data— это просто переменная, которая может содержать ссылку на значение или его адрес в куче. Так как он не указывает на адрес памяти, он называется пустой ссылкой.Создание экземпляра массива с помощью
intключевогоnewсловаОбновите код в редакторе Visual Studio Code, чтобы создать и назначить новый экземпляр массива
int, используя следующий код:int[] data; data = new int[3];Ключевое
newслово сообщает среде выполнения .NET, чтобы создать экземпляр массива, а затем координировать работу с операционной системой, чтобы сохранить размер массиваintдля трех значений int в памяти. Среда выполнения .NET следует этим предписаниям и возвращает адрес нового массиваintв памяти. Наконец, адрес памяти сохраняется в переменной. Элементы массиваintпо умолчанию имеют значение0, поскольку это значение по умолчанию для типаint.Изменение примера кода для выполнения обеих операций в одной строке кода
Как правило, две строки кода на предыдущем шаге сокращены до одной строки кода, чтобы объявить переменную и создать новый экземпляр массива
int. Измените код из шага 3 следующим образом.int[] data = new int[3];Хотя нет выходных данных для наблюдения, надеюсь, это упражнение добавило ясность в том, как синтаксис C# относится к шагам процесса для работы с ссылочными типами.
Что отличается от типа данных строки C#?
Тип данных string также является ссылочным. Возможно, вам интересно, почему new оператор не использовался при объявлении строки. Это сделано авторами языка C# исключительно в целях удобства,
string Так как тип данных используется так часто, можно использовать следующий формат:
string shortenedString = "Hello World!";
Console.WriteLine(shortenedString);
Однако за кулисами создается новый экземпляр System.String, который инициализируется как "Hello World!"
Практические проблемы с использованием типов значений и ссылок
-
Тип значения (int): в этом примере
val_Aиval_Bявляются целыми типами значений.
int val_A = 2;
int val_B = val_A;
val_B = 5;
Console.WriteLine("--Value Types--");
Console.WriteLine($"val_A: {val_A}");
Console.WriteLine($"val_B: {val_B}");
Должен появиться следующий результат:
--Value Types--
val_A: 2
val_B: 5
При val_B = val_A выполнении значение val_A копируется и сохраняется в val_B. Таким образом, когда val_B изменение изменяется, val_A остается небезопасным.
-
Ссылочный тип (массив): в этом примере
ref_Aиref_Bявляются ссылочными типами массивов.
int[] ref_A= new int[1];
ref_A[0] = 2;
int[] ref_B = ref_A;
ref_B[0] = 5;
Console.WriteLine("--Reference Types--");
Console.WriteLine($"ref_A[0]: {ref_A[0]}");
Console.WriteLine($"ref_B[0]: {ref_B[0]}");
Должен появиться следующий результат:
--Reference Types--
ref_A[0]: 5
ref_B[0]: 5
При ref_B = ref_A выполнении указывает на то же расположение памяти, ref_B что ref_Aи . Таким образом, при ref_B[0] изменении также изменяется, ref_A[0] так как они оба указывают на одно расположение памяти. Это ключевое различие между типами значений и ссылочными типами.
Кратко
- Типы значений имеют меньшие допустимые значения и хранятся в стеке. Ссылочные типы могут содержать большие значения, а экземпляр ссылочного типа создается с помощью оператора
new. Переменная ссылочного типа содержат ссылку (адрес памяти) на фактическое значение, хранящееся в куче. - К ссылочным типам относятся массивы, строки и классы.
Проверьте свои знания
Обратная связь
Были ли сведения на этой странице полезными?
Нет
Нужна помощь с этой темой?
Хотите попробовать использовать Ask Learn для уточнения или руководства по этой теме?