c#封装Get/Set
c# encapsulation Get/ Set
寻找有关 Get / Set 的一些说明。我有这个代码,我用它来创建我的对象..但是我想在 length
和 width
中进行 一些验证 (两者都需要更大比一些数字作为例子)。我相信 Get / Set 是可行的方法,我在更改实例中的字段时使用过它 - 但我如何在实例化阶段执行此操作?
class Room
{
public Double dblLength;
public Double dblWidth;
public Room (Double _dblLength, Double _dblWidth)
{
dblLength = _dblLength;
dblWidth = _dblWidth;
}
将字段转换为属性;在相应的 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;
}
}
如果你的 class 是不可变的,最简单的是:
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;
}
}
这是一个基于亚历克斯评论的示例。就我个人而言,我也会去掉下划线和 'dbl' 前缀,但我将它们留在里面以匹配问题。
您不能 return 来自构造函数的失败消息,因此抛出异常。
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;
}
}
如果它表明使用您的 class 的程序员不理解它,那么这是合适的。但是,如果很有可能在 运行 时间发生这种情况,您最好在对象中设置一个 '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;
}
}
您可以将字段更改为 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# 提供给我们的语法糖。编译此代码时,编译器将为每个 属性 创建两个方法 Get
和 Set
。因此,如果您在 getter 或 setter 上放置访问修饰符,编译器会考虑到这一点,并且在编译代码时,它会放置您指定的修饰符。但是,如果未指定特定修饰符,编译器将采用 属性 自身的修饰符,在上述情况下,Get
方法将为 public,而 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;
}
}
寻找有关 Get / Set 的一些说明。我有这个代码,我用它来创建我的对象..但是我想在 length
和 width
中进行 一些验证 (两者都需要更大比一些数字作为例子)。我相信 Get / Set 是可行的方法,我在更改实例中的字段时使用过它 - 但我如何在实例化阶段执行此操作?
class Room
{
public Double dblLength;
public Double dblWidth;
public Room (Double _dblLength, Double _dblWidth)
{
dblLength = _dblLength;
dblWidth = _dblWidth;
}
将字段转换为属性;在相应的 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;
}
}
如果你的 class 是不可变的,最简单的是:
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;
}
}
这是一个基于亚历克斯评论的示例。就我个人而言,我也会去掉下划线和 'dbl' 前缀,但我将它们留在里面以匹配问题。
您不能 return 来自构造函数的失败消息,因此抛出异常。
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;
}
}
如果它表明使用您的 class 的程序员不理解它,那么这是合适的。但是,如果很有可能在 运行 时间发生这种情况,您最好在对象中设置一个 '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;
}
}
您可以将字段更改为 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# 提供给我们的语法糖。编译此代码时,编译器将为每个 属性 创建两个方法 Get
和 Set
。因此,如果您在 getter 或 setter 上放置访问修饰符,编译器会考虑到这一点,并且在编译代码时,它会放置您指定的修饰符。但是,如果未指定特定修饰符,编译器将采用 属性 自身的修饰符,在上述情况下,Get
方法将为 public,而 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;
}
}