Конструктор Struct: «поля должны быть полностью назначены до того, как управление будет возвращено вызывающей стороне». - PullRequest
103 голосов
/ 29 марта 2010

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

  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' должно быть полностью назначается до того, как управление возвращается звонящий. Подумайте о том, чтобы позвонить конструктор по умолчанию из конструктора инициализатор.

Что я делаю не так?

Ответы [ 4 ]

289 голосов
/ 11 марта 2011

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

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

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

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

49 голосов
/ 29 марта 2010

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

У структуры нет способа иметь конструктор без параметров, поэтому рассмотрите возможность изменения его на класс.

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

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

construct(params) : this()

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

30 голосов
/ 29 марта 2010

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

public AttackTraits(double probability, int damage, float distance)
{
    this.probability = 0;
    Distance = distance;
    Damage = damage;
}
2 голосов
/ 29 марта 2010

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

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

_probability = probability;

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

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