Почему установка свойства в конструкторе структуры не работает? - PullRequest
6 голосов
/ 01 марта 2011

У меня следующий код, который не разрешен (ошибка ниже), почему?

    struct A
    {
        private int b;

        public A(int x)
        {
            B = x;
        }
        public int B
        {
            get { return b; }
            set { b=value; }
        }

    }

Я получаю следующую ошибку:

Объект 'this' нельзя использоватьпрежде чем все его поля будут присвоены полю «Test.x» необходимо полностью назначить, прежде чем управление будет возвращено вызывающей стороне

Ответы [ 3 ]

4 голосов
/ 01 марта 2011

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

1) Вы можете явно вызвать конструктор без параметров:

public A(int x) : this()
{
    B = x;
}

2) Вы можете использовать поле вместо свойства:

public A(int x)
{
    b = x;
}

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

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

struct A
{
    private readonly int b;

    public A(int x)
    {
        b = x;
    }

    public int B { get { return b; } }
}

РЕДАКТИРОВАТЬ: Подробнее о том, почему оригинальный код не работает ...

Из раздела 11.3.8 спецификации C #:

Если конструктор экземпляра структуры не указывает инициализатор конструктора, переменная this соответствует параметру out типа структуры

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

1 голос
/ 01 марта 2011

С MSDN"Внутри объявления структуры поля не могут быть инициализированы, если они не объявлены как постоянные или статические."

1 голос
/ 01 марта 2011

Измените ваш конструктор на:

public A(int x) :
    this()
{
    B = x;
}

Что касается «почему», обратитесь к 11.3.8 Конструкторы и 5.3 Определенное назначение .

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