我正在寻找一些类或数据类型,以便我可以定义它的范围。
以下是我正在寻找的伪代码:
[Range(0, 75)] int ChildAge;
应该将此范围规则应用于分配给本年龄的任何int,如下所示。
var MotherAge = ChildAge;
MotherAge = 100;
母亲年龄应该设置为75岁,这就是我要寻找的内容。
struct Age
{
const int MinAge = 0;
const int MaxAge = 75;
readonly byte value;
public int Value { get { return value; } }
private Age(int value) {
this.value = (byte) Math.Max(MinAge, Math.Min(MaxAge, value));
}
public static implicit operator Age(int value) {
// Throw here if value is out of range, maybe?
return new Age(value);
}
public static implicit operator int(Age age) {
return age.value;
}
}
//usage:
Age childAge = 12; // 12
Age motherAge = 100; // 75
编辑:需要指出的是,将“有损”转换暴露为隐式转换通常被认为是不好的实践。我应该将operator int(Age)
转换改为explicit
。这将需要编写一个显式转换Age age = (Age) 100;
,它向API的使用者广告宣传了转换不是“保持身份”的。这类似于从long
到int
或从double
到float
的转换,存在范围/精度损失,因此语言要求您明确表示您理解自己在做什么。
C#中没有这样的功能,但是您可以创建一个处理它的类:
public class Age
{
public Age(int age) : this(0, 75, age) { }
public Age(int minAge, int maxAge) : this(minAge, maxAge, minAge) { }
public Age(int minAge, int maxAge, int age)
{
this._Minimum = minAge;
this._Maximum = maxAge;
this.Value = age;
}
private int _Value = 0;
public int Value
{
get
{
return _Value;
}
set
{
CheckRange(value, true);
}
}
private int _Maximum = 0;
public int MaximumAge
{
get
{
return _Maximum;
}
set
{
if (value < _Minimum)
throw new ArgumentException("MaximumAge");
_Maximum = value;
CheckRange(value, false);
}
}
private int _Minimum = 0;
public int MinimumAge
{
get
{
return _Minimum;
}
set
{
if (value > _Maximum)
throw new ArgumentException("MinimumAge");
_Minimum = value;
CheckRange(value, false);
}
}
private void CheckRange(int value, bool setValueAnyway)
{
if (value < _Minimum)
_Value = _Minimum;
else if (value > _Maximum)
_Value = _Maximum;
else if (setValueAnyway)
_Value = value;
}
}
Age childAge = new Age(0,75);
Age motherAge = childAge;
motherAge.Value = 100; // 75
您不需要使用属性,可以使用 property
:
private int _age;
public int ChildAge
{
get { return _age; }
set
{
if(value > 75)
_age = 75;
else if(value < 0)
_age = 0;
else
_age = value;
}
}
_age = LimitValue(value, 0, 75);
,并且可以适当地重用 LimitValue
。 - Dan Puzey
Age
的class
,其中包含min
、max
和value
属性。然后添加一个方法void SetRange(Age a)
来设置相等的范围。 - Koryu