Вопрос

Is it possible to specify that a enum property can only have a range of values?

enum Type
{
    None,
    One,
    Two,
    Three
}

class Object
{
    [AllowedTypes(Type.One,Type.Three)]
    Type objType { get; set; }
}

Something like this? Maybe some validator in enterprise library that I don't know of ?!

Ty

Это было полезно?

Решение

You could do the validation in setter logic.

EDIT: some example:

class Object
{
    private Type _value;

    public Type objType{ 

        get{ return _value; }
        set{
            if(value != Type.One && value != Type.Three)
                throw new ArgumentOutOfRangeException();
            else
                _value = value;
        }
    }
}

Другие советы

Same as st4hoo's solution, only with reflection. You can make it as crazy as you would like.

using System;
using System.Linq;

namespace ConceptApplication
{
    static class Program
    {
        static void Main(string[] args)
        {
            var foobar = new Foobar
            {
                SomeProperty = Numbers.Five
            };
        }
    }

    public class Foobar
    {
        private static Numbers _someProperty;

        [NumberRestriction(Allowed = new[] {Numbers.One, Numbers.Two})]
        public Numbers SomeProperty
        {
            get { return _someProperty; }
            set
            {
                RestrictionValidator.Validate(this, "SomeProperty", value);

                _someProperty = value;
            }
        }
    }

    public class NumberRestriction : Attribute
    {
        public Numbers[] Allowed { get; set; }
    }

    public static class RestrictionValidator
    {
        public static void Validate<T>(T sender, string propertyName, Numbers number)
        {
            var attrs = sender.GetType().GetProperty(propertyName).GetCustomAttributes(typeof(NumberRestriction), true);

            if (attrs.OfType<NumberRestriction>().Any(attr => !(attr).Allowed.Contains(number)))
                throw new ArgumentOutOfRangeException();
        }
    }

    public enum Numbers
    {
        One,
        Two,
        Three,
        Four,
        Five
    }
}

Another way to approach this is through front-end validation / filtering. I encountered a scenario where, on the db level, I needed to allow the db to save a field to any of the enum values, but I didn't want the end user to see invalid options. So, I created an attribute for the enum values specifying what kind of user could see those enum values.

public class FieldAttribute : Attribute
{
    public int FilterProperty { get; set; }
}

Then I decorated the enum values with that attribute.

public enum myEnum{

    ZeroValue,

    [Field(FilterProperty = 0)]
    FirstValue,

    [Field(FilterProperty = 1)]
    SecondValue,

    [Field(FilterProperty = 0)]
    ThirdValue,

    [Field(FilterProperty = 1)]
    FourthValue,
}

then i created an extension method that provided a dictionary of only the values that type of user could see.

        public static IDictionary<int, string> PrepareAcceptableValues(int filterVal) {
        var values = Enum.GetValues(typeof(myEnum));

        var retval = new List<myEnum>();
        foreach (var value in values) {

            try { //if enum value has an attribute type...
                var assignedFilterProp = value.GetType().GetMember(value.ToString()).First().GetCustomAttribute<FieldAttribute>().FilterProperty;

                if (assignedFilterProp.Equals(filterVal)) //if enum value has the correct filter property
                    retval.Add((myEnum)value); //add it in
            }
            catch (Exception e) {
                retval.Add((myEnum)value); //if enum value has no attribute, add it in
            }
        }

        return retval.ToDictionary(i => (int)i, i => i.toString());

Then, when the data came in on the front end, as long as whatever they pick is part of the base enum, the DB can save it.

Not really answering your question directly, but an indirect route that might help you get what you're after.

You could do a workaround like this:

static MyEnumType[] allowedEnumTypes = {MyEnumType.One, MyEnumType.Two};

MyEnumType _myEnumObject = allowedEnumTypes.First();
MyEnumType MyEnumObject
{
    get
    {
        return _myEnumObject;
    }
    set
    {
        if(!allowedEnumTypes.Any (et => et == value))
        {
            throw new Exception("Enum value not allowed.");
        }
        _myEnumObject = value;
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top