我有一个struct
和一个整数变量。我的变量值必须介于1200和1599之间。但在默认构造函数中,我无法控制变量值。我如何在struct
?
struct MyStruct
{
public int x;
public MyStruct(int x)
{
if(x>1599)
this.x=1599;
else if(x<1200)
this.x=1200;
else
this.x=x;
}
}
答案 0 :(得分:2)
使用具有支持字段的属性:
struct MyStruct
{
private const int MIN_VALUE = 1200;
private const int MAX_VALUE = 1599;
private int x;
public int X
{
get { return x + MIN_VALUE; }
set
{
if(value > MAX_VALUE)
x = MAX_VALUE;
else if(value < MIN_VALUE)
x = MIN_VALUE;
else
x = value;
x -= MIN_VALUE;
}
}
// constructor is not really needed anymore, but can still be added
}
我将该属性与我的setter和Damien_The_Unbeliever的getter相结合,以获得x
的初始状态。我也同意蒂姆关于&#34;魔术数字&#34;的常数。并补充说。所以请把这两个也归功于&#34;我的答案&#34;。
同样,DatVM已经说过:根据常见的C#命名指南,公共字段/属性应该以大写字母开头。这也使你在支持字段中使用相同的名称,但从一个小写字母开始(我个人不喜欢丑陋的_)...
最后但并非最不重要的一点:请阅读rexcfnghk的回答,即使这不是一个真正的答案,因为他也是绝对正确的。
答案 1 :(得分:2)
使用属性和私有支持字段的另一种变体:
struct MyStruct
{
private int x;
public MyStruct(int x)
{
if (x > 1599)
this.x = 399;
else if (x < 1200)
this.x = 0;
else
this.x = x - 1200;
}
public int X { get { return x+1200; } }
}
确保默认构造值为&#34;范围为&#34;。
但是任何变体都会引入一些开销,所以这取决于你是否可以接受。
答案 2 :(得分:1)
我的变量值必须介于1200和1599之间
在C#中,您无法为struct
定义自己的默认构造函数。如果您有一个MyStruct
数组,例如var myArray = new MyStruct[5]
,则会调用MyStruct
的默认构造函数,而myArray
中的元素将x
等于struct
0,根据您的要求无效。
这就是为什么我认为您的设计不正确struct
。根据{{3}}
√ DO 确保所有实例数据都设置为零,false或null(视情况而定)的状态有效。
这可以防止在创建结构数组时意外创建无效实例。
如果在调用class
的默认构造函数时需要参数验证,请改用MyStruct
。
此外,您当前的{{1}}设计使其变得可变。请看一下为什么Framework Design Guidelines。
答案 3 :(得分:1)
我会使用带有getter和setter的属性以及一个私有支持字段,您可以在其中实现此逻辑,如果值超出边界,甚至可以抛出ArgumentOutOfRangeException
。
以下是一个例子:
struct MyStruct
{
private const int MIN_VALUE = 1200;
private const int MAX_VALUE = 1599;
private int _X;
public int X
{
get { return _X; }
set { _X = checkBoundaries(value); }
}
private static int checkBoundaries(int x)
{
if (x > MAX_VALUE)
return MAX_VALUE;
else if (x < MIN_VALUE)
return MIN_VALUE;
else
return x;
}
public MyStruct(int x)
{
_X = checkBoundaries(x);
}
}
即使您不需要首先限制访问权限,也始终使用属性是一种很好的做法。如果需要,可以更容易地实现这样的逻辑。
最后一点说明:我建议使用一个类而不是struct。
_X
。_X
with the minimum value inline,因为结构中也不允许这样做答案 4 :(得分:0)
您应该将x更改为property
而不是:
private int _x;
public int x {
get
{
return _x;
}
set
{
_x = value;
if (_x > 1599)
{
_x = 1599
}
else if (_x < 1200)
{
_x = 1200
}
}
}
P.S:对于C#命名约定,它应该被称为X
(大写)而不是x
答案 5 :(得分:0)
如果结构使用私有字段和公共属性来转换字段的值,使其默认值映射,则可以使结构具有默认值,而不是使用公共字段。到结构的所需默认值。例如,您可以拥有一个支持字段int _x_minus_1200;
并拥有一个返回_x_minus_1200 + 1200
的属性getter。我并不非常热衷于这种方法(通常我更喜欢结构具有公共字段和行为类似结构,并且结构字段的含义和验证是使用结构的代码的函数)但在某些情况下他们可以提供帮助。