是否可以在C#(.NET)中使用范围变量

Moh*_*kar 3 .net c# vb.net c#-3.0 c#-4.0

我正在寻找一些类或数据类型,以允许我为它定义一个范围.
这是我正在寻找的伪代码:

[Range(0, 75)] int ChildAge;
Run Code Online (Sandbox Code Playgroud)

此范围规则应应用于此年龄分配的任何int,如下所示

var MotherAge = ChildAge;
MotherAge = 100; 
Run Code Online (Sandbox Code Playgroud)

MotherAge应该设置为75,这就是我正在寻找的.

Mar*_*lug 7

另一种选择是定义您自己的数据类型以表示年龄值.此类型可以强制执行约束.

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
Run Code Online (Sandbox Code Playgroud)

编辑:我想指出,将"有损"转换暴露为隐式转换通常被认为是不好的做法.我应该做出operator int(Age)转换explicit.这将需要编写一个显式的强制转换Age age = (Age) 100;,它向API的消费者宣传该强制转换不是"身份保留".这类似于从铸造longintdoublefloat,有范围/精度损失,因此语言需要你显式地说明,以证明你知道你在做什么.


Tim*_*ter 6

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您的样本老化:

Age childAge = new Age(0,75);
Age motherAge = childAge;
motherAge.Value = 100;   // 75
Run Code Online (Sandbox Code Playgroud)