Почему компилятор C # вызывает явную инициализацию всех полей типа значения в конструкторе? - PullRequest
0 голосов
/ 24 сентября 2018

Для класса это нормально:

class Point
{
    private int _x, _y;

    public Point(int x)
    {
        _x = x;
    }
}

Но если я использую тип значения, компилятор жалуется, что _y не инициализирован:

struct Point
{
    private int _x, _y;

    public Point(int x)
    {
        _x = x;
    }
}

I 'Мне интересно, что за этим стоит обоснование ?Почему компилятор не может просто инициализировать _y в 0, как это происходит при отсутствии явного конструктора?

Ответы [ 3 ]

0 голосов
/ 24 сентября 2018

Вы можете сделать это следующим образом, теперь все типы значений инициализированы:

struct Point
{
    private int _x, _y;

    public Point(int x)
        :this()
    {
        _x = x;
    }
}

Обратите внимание, я просто назвал конструктор по умолчанию.

Я думаю, что причина такого поведения,что если вы вызываете конструктор по умолчанию или указываете все поля в конструкторе с параметрами, это показывает, что вы знаете, что делаете, и не случайно инициализируете некоторые поля по умолчанию.

0 голосов
/ 24 сентября 2018

Это можно найти в Разделе 5.3.1 спецификации C #, в которой говорится, что изначально присваиваются следующие типы переменных.Список для целей:

  • Переменные экземпляра экземпляров класса.
  • Переменные экземпляра изначально назначенных переменных структуры.
  • Элементы массива.
  • Значения параметров.
  • Ссылочные параметры.
  • Переменные, объявленные в предложении catch или в выражении foreach.

Следующее даст вамзначение 0:

Point p = new Point(10);
Console.WriteLine(p.y);

Поскольку переменные инициализируются в их значения по умолчанию, которые могут привести к ошибкам в коде, компилятор предупреждает о неинициализированных переменных.

Это само по себе не будетcompile:

int temp;
Console.WriteLine(temp);

Джон Скит дает хороший ответ здесь:

Неинициализированная переменная в C #

0 голосов
/ 24 сентября 2018

Почему?Поскольку спецификация языка (ECMA 334 16.4.9) гласит:

Ни один член функции экземпляра (включая установленные методы доступа для свойств X и Y) не может быть вызван до тех пор, пока все поля структуры не будут созданыбыли определенно назначены.Однако обратите внимание, что если бы Point был классом, а не структурой, реализация конструктора экземпляра была бы разрешена.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...