C # инкапсуляция Get / Set - PullRequest
       43

C # инкапсуляция Get / Set

0 голосов
/ 02 октября 2018

ищет уточнения по Получить / Установить .У меня есть этот код, который я использую для создания своих объектов. Как бы то ни было, я хочу получить некоторую проверку с length и width (оба должны быть больше, чем некоторое число в качестве примера).Я считаю, Get / Set - это путь, и я использовал это при изменении полей в экземпляре, но как мне это сделать на этапе создания экземпляра?

class Room
{
    public Double dblLength;
    public Double dblWidth;

    public Room (Double _dblLength, Double _dblWidth)
    {

        dblLength = _dblLength;
        dblWidth = _dblWidth;
    }

Ответы [ 4 ]

0 голосов
/ 02 октября 2018

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

Пример:

class Room
    {
        private double _dblLength;
        private double _dblWidth;

        public double DblLength {
            get
            {
                return _dblLength;
            }
            set
            {
                //TODO -> Do validation
                //the keyword value represents the value that you want to pass to the property
                if(value < 0)
                {
                    throw new ArgumentOutOfRangeException("message");
                }

                _dblLength = value;
            }
        }
        public double DblWidth
        {
            get
            {
                return _dblWidth;
            }
            set
            {
                //TODO -> Do validation
                //the keyword value represents the value that you want to pass to the property
                if (value < 1)
                {
                    throw new ArgumentOutOfRangeException("message");
                }

                _dblWidth = value;
            }
        }

        public Room(Double _dblLength, Double _dblWidth)
        {
            DblLength = _dblLength;
            DblWidth = _dblWidth;
        }
    }   

Еще одна полезная вещь: если вы хотите, чтобы свойства устанавливались только при создании экземпляра (только через конструктор), вы можете сделать установщик private следующим образом:

class Room
    {
        private double _dblLength;
        private double _dblWidth;

        public double DblLength {
            get
            {
                return _dblLength;
            }
            private set
            {
                //TODO -> Do validation
                //the keyword value represents the value that you want to pass to the property
                if(value < 0)
                {
                    throw new ArgumentOutOfRangeException("message");
                }

                _dblLength = value;
            }
        }
        public double DblWidth
        {
            get
            {
                return _dblWidth;
            }
            private set
            {
                //TODO -> Do validation
                //the keyword value represents the value that you want to pass to the property
                if (value < 1)
                {
                    throw new ArgumentOutOfRangeException("message");
                }

                _dblWidth = value;
            }
        }

        public Room(Double _dblLength, Double _dblWidth)
        {
            DblLength = _dblLength;
            DblWidth = _dblWidth;
        }
    }

Это возможно, потому что свойства - это просто синтаксический сахар, предоставленный нам C #.Когда этот код скомпилирован, компилятор создаст два метода Get и Set для каждого свойства.Таким образом, если вы поместите модификатор доступа в геттер или сеттер, компилятор примет это во внимание, и когда он скомпилирует код, он поместит указанный вами модификатор.Однако, если не указан конкретный модификатор, компилятор примет модификатор самого свойства в приведенном выше случае, метод Get будет открытым, а метод Set - закрытым.После компиляции код будет выглядеть примерно так:

class Room
{
    private double _dblLength;
    private double _dblWidth;

    public Room(Double _dblLength, Double _dblWidth)
    {
        SetDblLength(_dblLength);
        SetDblWidth(_dblWidth);
    }

    public double GetDblLength()
    {
        return _dblLength;
    }

    private void SetDblLength(double value)
    {
        if (value < 0)
        {
            throw new ArgumentOutOfRangeException("message");
        }

        _dblLength = value;
    }

    public double GetDblWidth()
    {
        return _dblWidth;
    }

    private void SetDblWidth(double value)
    {
        if (value < 0)
        {
            throw new ArgumentOutOfRangeException("message");
        }

        _dblWidth = value;
    }
}
0 голосов
/ 02 октября 2018

Если ваш класс неизменный, самый простой:

class Room
{
    public double Length { get; }
    public double Width { get; }

    public Room(double length, double width)
    {
        // Validation here, for instance throw exception if length <= 0
        Length = length;
        Width = width;
    }
}

Использование C # 6 только для чтения автоматических свойств .

0 голосов
/ 02 октября 2018

Вот пример, основанный на комментарии Алекса.Лично я бы также избавился от подчеркиваний и префикса 'dbl', но я оставил их, чтобы соответствовать вопросу.

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

class Room
  {
  private Double dblLength;
  private Double dblWidth;

  public Room (Double _dblLength, Double _dblWidth)
  {
    if (_dblLength < _dblWidth)
    {
        throw new ArgumentException("length must be more than width");
    }

    dblLength = _dblLength;
    dblWidth = _dblWidth;
  }
}

Это уместно, если указывает, что программист, использующий ваш класс, не понимает этого.Однако, если есть хорошие шансы на то, что это произойдет во время выполнения, вам может быть лучше иметь в объекте флаг hasError, который не позволяет сохранить его или делать что-либо еще.

  class Room
  {
    private Double dblLength;
    private Double dblWidth;

    public bool HasError {get;}

    public Room (Double _dblLength, Double _dblWidth)
    {
      if (_dblLength < _dblWidth)
      {
          HasError = true;
      }

      dblLength = _dblLength;
      dblWidth = _dblWidth;
    }

    public Save()
    {
        if (HasError) return;
        // Otherwise do the save;
    }
}
0 голосов
/ 02 октября 2018

Превратить поля в свойства ;осуществить проверку в пределах соответствующего set:

class Room
{
    private Double m_DblLength;
    private Double m_DblWidth;

    public Room (Double _dblLength, Double _dblWidth) {
      DblLength = _dblLength;
      DblWidth = _dblWidth;
    }

    public Double DblLength {
      get {
        return m_DblLength;
      }
      set {
        //TODO: validation here
        if (value < 0)
          throw new ArgumentOutOfRangeException("value"); 

        m_DblLength = value;
      }
    }

    public Double DblWidth {
      get {
        return m_DblWidth;
      }
      set {
        //TODO: validation here
        if (value < 0)
          throw new ArgumentOutOfRangeException("value"); 

        m_DblWidth = value;
      }
    }
...