Конструктор конструкций: "поля должны быть полностью назначены до того, как элемент управления будет возвращен вызывающему".

Вот структура, которую я пытаюсь написать:

  public struct AttackTraits
        {
            public AttackTraits(double probability, int damage, float distance)
            {
                Probability = probability;
                Distance = distance;
                Damage = damage;
            }

            private double probability;
            public double Probability
            {
                get
                {
                    return probability;
                }
                set
                {
                    if (value > 1 || value < 0)
                    {
                        throw new ArgumentOutOfRangeException("Probability values must be in the range [0, 1]");
                    }
                    probability = value;
                }
            }

            public int Damage { get; set; }

            public float Distance { get; set; }
        }

Это приводит к следующим ошибкам компиляции:

Объект 'this' нельзя использовать прежде чем все его поля будут назначены до

Поле "AttackTraits.probability" должно быть полностью назначены до того, как управление будет возвращается вызывающему абоненту

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

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

Что я делаю неправильно?

Ответ 1

Вы устанавливаете поле probability через свойство probability, но компилятор не знает, что свойство задает поле... поэтому вам нужно явно инициализировать само поле вероятности

public AttackTraits(double probability, int damage, float distance)
{
    this.probability = 0;
    Distance = distance;
    Damage = damage;
}

Ответ 2

Если вы видите эту ошибку в структуре с автоматическим свойством, просто вызовите конструктор без параметров из вашего параметризованного, выполнив : this() пример ниже:

struct MyStruct
{
  public int SomeProp { get; set; }

  public MyStruct(int someVal) : this()
  {
     this.SomeProp = someVal;
  }
}

Вызывая: this() из вашего объявления конструктора, вы позволяете базовому классу ValueType инициализировать все поля поддержки для автоматических свойств. Мы не можем сделать это вручную на нашем конструкторе, потому что у нас нет доступа к полю резервного копирования автоматического свойства. ValueType - это базовый класс всех структур.

Ответ 3

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

Нет никакого способа, чтобы структура имела конструкцию без параметров, поэтому рассмотрите ее вместо этого вместо класса.

Лучшей практикой является использование структур только в том случае, если они равны 16 байтам и являются неизменными. Поэтому, если вы собираетесь изменять поля объектов после создания, подумайте о его рефакторинге в классе.

Кроме того, вы можете изменить определение конструктора:

construct(params) : this()

это также устранит ошибку.

Ответ 4

Измените строку Probability = probability на this.probability = probability

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

_probability = probability;

и легко увидеть, что происходит.