Domanda

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.

È stato utile?

Soluzione

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.

Altri suggerimenti

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;

   } 
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top