Question

I'm looking for some class or data type to allow me define a range for it.
This is the pseudo code which I'm looking for :

[Range(0, 75)] int ChildAge;

This range rule should be applied to any int which this Age is assigned like following

var MotherAge = ChildAge;
MotherAge = 100; 

MotherAge should be set to 75 and this is what I'm looking for.

Was it helpful?

Solution

Another option would be to define your own data type to represent age values. This type could enforce the constraints.

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

Edit: I would point out that it is generally considered bad practice to have "lossy" conversions exposed as implicit casts. I should have made the operator int(Age) conversion explicit instead. This would require writing an explicit cast Age age = (Age) 100; which advertises to the consumer of the API that the cast isn't "identity preserving". This is similar to a cast from long to int or double to float, there is a loss of range/precision so the language requires you be explicit about it to demonstrate that you understand what you are doing.

OTHER TIPS

There is no such thing in C#, but you could create a class that handles it easily:

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;
    }
}

Now your sample ages:

Age childAge = new Age(0,75);
Age motherAge = childAge;
motherAge.Value = 100;   // 75

You don't need an attribute. You can use a 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;

   } 
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top