C#封装获取/设置

时间:2018-10-02 07:59:47

标签: c# get set encapsulation

寻找有关获取/设置的说明。我有用于创建对象的这段代码。但是,我想使用lengthwidth进行一些验证(两者都必须大于某个数字例如)。我相信获取/设置是解决问题的方法,并且我在更改实例中的字段时已经使用了它-但是在实例化阶段该如何做?

class Room
{
    public Double dblLength;
    public Double dblWidth;

    public Room (Double _dblLength, Double _dblWidth)
    {

        dblLength = _dblLength;
        dblWidth = _dblWidth;
    }

4 个答案:

答案 0 :(得分:4)

字段转换为 properties ;在相应的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;
      }
    }

答案 1 :(得分:1)

如果您的班级是一成不变的,最简单的方法是:

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's readonly auto properties

答案 2 :(得分:0)

这是一个示例,基于Alex的评论。就个人而言,我也要删除下划线和'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;
    }
}

答案 3 :(得分:0)

您可以将字段更改为properties。将字段更改为属性后,可以验证将设置为依据属性的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;
        }
    }   

另一件事是,如果您希望仅在创建实例时(仅通过构造函数)设置属性,则可以像下面这样设置setter 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#提供给我们的语法糖。编译此代码后,编译器将为每个属性创建两个方法GetSet。因此,如果将访问修饰符放在getter或setter上,编译器将牢记这一点,并且在编译代码时,它将放置您指定的修饰符。但是,如果未指定特定的修饰符,则在上述情况下,编译器将采用属性本身的修饰符,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;
    }
}