Почему для добавления примитивной структуры в список не требуется ключевое слово new. Принимая во внимание, что для добавления непримитивной структуры в список требуется новое ключевое слово? - С#

Добавление примитива struct (например, int) к List:

int i=10;
List<int> list=new List<int>();
list.Add(i);

Против: Добавление непримитивного struct (например, KeyValuePair<int,int>) в список:

List<KeyValuePair<int, int>> list = new List<KeyValuePair<int, int>>();
list.Add(new KeyValuePair<int,int>(10,20));

При добавлении intstruct к list нам не нужно использовать ключевое слово new. Но при добавлении KeyValuePairstruct в список нам нужно использовать ключевое слово new.

Я имею в виду, что следующее утверждение неверно:

list.Add(new int(10)); //invalid statement

Хотя и int, и KeyValuePair являются структурами, они ведут себя по-разному — не требуется создание экземпляра перед использованием (с точки зрения пользователя). А другой требует создания экземпляра перед использованием.

Почему мы не можем сделать следующее вместо этого:

list.Add(KeyValuePair<int,int>(10,20)) //omit the new keyword, as we were doing with an int

Исходя из опыта работы с C/C++, что именно делает ключевое слово new в C#? Он просто создает экземпляр базового типа данных (и мы не уверены, будет ли экземпляр типа данных лежать в стеке или в куче). Или мы уверены, что использование нового ключевого слова выделит память в куче (как это делается в C++)?

Прочитайте мой ответ на этот вопрос stackoverflow.com/questions/65418824/…. Это не дает прямого ответа на ваш вопрос, но должно сделать ответ очевидным

Flydog57 25.12.2020 05:45

«При добавлении структуры int в список нам не нужно использовать новое ключевое слово. Но при добавлении структуры KeyValuePair в список нам нужно использовать новое ключевое слово» — это совершенно неверно. В принципе, ваш вопрос сломан. Примеры, которые вы называете чем-то принципиально отличным, на самом деле ничем не отличаются. Это правда, что у System.Int32 нет конструктора с параметром. Но вы, конечно, можете написать new int(). ...

Peter Duniho 25.12.2020 05:47

... Более того, вы также можете назвать переменную i, объявив ее как KeyValuePair<int, int>, а затем добавить в список, используя точно такой же синтаксис, как в первом примере, то есть list.Add(i);. Разницы нет, поэтому спрашивать, почему есть разница, не имеет никакого смысла.

Peter Duniho 25.12.2020 05:48

Для получения дополнительной информации, помимо очевидного чтения документации по языку, вы также можете просмотреть вопросы о переполнениях стека stackoverflow.com/questions/9207488/… и stackoverflow.com/questions/11504910/…

Peter Duniho 25.12.2020 05:50

И, что бы это ни стоило, когда тип имеет буквальное представление, вы можете думать о литерале как о «константной» версии new T (LiteralOfT). Такое выражение, как int i = 10;, очень близко к int i = new int(10). Ключевое слово new выделяет память из управляемой кучи, а затем запускает конструктор для ссылочных типов, как в C++. Ключевое слово new для типов значений просто запускает конструктор и не выделяет память. Затем результат построенного объекта копируется в переменную.

Flydog57 25.12.2020 05:53

Вопрос интересный, даже если плохо написан. Почему вы можете инициализировать определенные типы (int, string, ...) без использования ключевых слов new (или default())? А ответ сводится к существованию литералов (и константных выражений (можно int x = (int)5.5))

xanatos 25.12.2020 09:39
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

что именно делает новое ключевое слово в С#?

Все это здесь. Наиболее актуальным для этого вопроса является «вызов конструктора». Структуры и классы имеют конструкторы, а конструкторы создают экземпляры структур и классов.

Когда вы делаете:

new KeyValuePair<int,int>(10,20)

вы вызываете этот конструктор.

int, который является псевдонимом для структуры Int32, не имеет конструктора, который принимает параметр типа int. Вот почему вы не можете сделать:

new int(10)

Обратите внимание, что вызов конструктора — не единственный способ создать экземпляр структуры. Вы также можете сделать что-то вроде:

var defaultKVP = default(KeyValuePair<int, int>); // gets the default value of the type KeyValuePair<int, int>
// defaultKVP is an instance of KeyValuePair<int, int>! It's not null! Structs can't be null :)

Значение по умолчанию структуры определяется путем установки для всех ее полей с типом значения значения по умолчанию, а для полей ссылочного типа — значение null.

Причина, по которой целочисленный литерал вроде 10 является экземпляром структуры Int32, кроется в магии компилятора. Спецификация так говорит, поэтому так и реализовано.

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