Почему я не могу определить конструктора по умолчанию для структуры в.NET?

242
задан Community 23 May 2017 в 02:34
поделиться

7 ответов

<забастовка> Примечание: ответ ниже был записан долгое время до C# 6, который планирует представить способность объявить конструкторов без параметров в структурах - но их все еще не назовут во всех ситуациях (например, для создания массива) (в конце, эта опция не была добавлена к C# 6).

<час>

РЕДАКТИРОВАНИЕ: я отредактировал ответ ниже должного к пониманию Grauenwolf CLR.

CLR позволяет типам значения иметь конструкторов без параметров, но C# не делает. Я полагаю, что это вызвано тем, что это представило бы ожидание, что конструктора вызовут, когда это не было бы. Например, рассмотрите это:

MyStruct[] foo = new MyStruct[1000];

CLR в состоянии сделать это очень эффективно только путем выделения соответствующей памяти и обнуления всего этого. Если бы это должно было выполнить конструктора MyStruct 1000 раз, который был бы намного менее эффективным. (На самом деле это не делает - если Вы делаете , имеют конструктора без параметров, это не становится выполненным при создании массива, или когда у Вас есть неинициализированная переменная экземпляра.)

основное правило в C# является "значением по умолчанию для любого типа, не может полагаться ни на какую инициализацию". Теперь они могли позволять конструкторам без параметров быть определенными, но тогда не требуемый, что конструктор, который будет выполнен во всех случаях - но это привело бы к большему количеству беспорядка. (Или по крайней мере, таким образом, я верю, аргумент идет.)

РЕДАКТИРОВАНИЕ: Для использования примера, что было бы Вы хотеть произойти, когда кто-то сделал:

Rational[] fractions = new Rational[1000];

это должно пробежать Вашего конструктора 1000 раз?

  • В противном случае мы заканчиваем с 1 000 недопустимых rationals
  • , Если они делают, тогда мы потенциально потратили впустую загрузку работы, если мы собираемся заполнить массив с действительными значениями.

РЕДАКТИРОВАНИЕ: (Отвечающий на немного большее количество вопроса), конструктор без параметров не создается компилятором. Типы значения не должны иметь конструкторов, насколько CLR затронут - хотя оказывается, что это может , если Вы пишете его в IL. Когда Вы пишете" new Guid()" в C#, который испускает различный IL к тому, что Вы получаете при вызове нормального конструктора. См. это ТАК вопрос некоторое время больше на том аспекте.

я подозреваемый , что нет никаких типов значения в платформе с конструкторами без параметров. Несомненно NDepend мог сказать мне, если бы я спросил его достаточно приятно... То, что C# запрещает его, является достаточно большой подсказкой для меня, чтобы думать, что это - вероятно, плохая идея.

187
ответ дан Community 23 November 2019 в 03:14
поделиться

Структура является типом значения, и тип значения должен иметь значение по умолчанию, как только это объявляется.

MyClass m;
MyStruct m2;

, Если Вы объявляете два поля как выше, не инстанцируя также, затем повредите отладчик, m будет пустым, но m2 не будет. Учитывая это, конструктор без параметров не имел бы никакого смысла, на самом деле весь любой конструктор на структуре делает, присваивают значения, сама вещь уже существует только путем объявления его. Действительно m2 мог вполне счастливо использоваться в вышеупомянутом примере и называть его методы, если таковые имеются, и его поля и свойства, которыми управляют!

44
ответ дан Tarik 23 November 2019 в 03:14
поделиться

Можно сделать статическое свойство, которое инициализирует и возвращает "рациональное" число по умолчанию:

public static Rational One => new Rational(0, 1); 

И использование это как:

var rat = Rational.One;
14
ответ дан AustinWBryan 23 November 2019 в 03:14
поделиться

Более короткое объяснение:

В C++, структура и класс были всего двумя сторонами той же монеты. Единственная реальная разница - то, что каждый был общедоступен по умолчанию, и другой было частным.

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

13
ответ дан Peter Mortensen 23 November 2019 в 03:14
поделиться

Просто особый случай это. Если Вы видите числитель 0 и знаменатель 0, притворяетесь как он, имеет значения, которые Вы действительно хотите.

2
ответ дан Jonathan Allen 23 November 2019 в 03:14
поделиться

Вы не можете определить конструктора по умолчанию, потому что Вы используете C#.

Структуры могут иметь конструкторов по умолчанию в.NET, хотя я не знаю ни о каком определенном языке, который поддерживает ее.

1
ответ дан Jonathan Allen 23 November 2019 в 03:14
поделиться

То, что я использую, объединяющий пустой указатель оператор (??) объединенный с отступающим полем как это:

public struct SomeStruct {
  private SomeRefType m_MyRefVariableBackingField;

  public SomeRefType MyRefVariable {
    get { return m_MyRefVariableBackingField ?? (m_MyRefVariableBackingField = new SomeRefType()); }
  }
}

Hope это помогает ;)

Примечание: пустое присвоение объединения в настоящее время является предложением по функции по C# 8.0.

1
ответ дан 23 November 2019 в 03:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: