在属性中指定允许的枚举值

时间:2014-05-15 13:03:11

标签: c# enums enterprise-library validation

是否可以指定枚举属性只能有一系列值?

enum Type
{
    None,
    One,
    Two,
    Three
}

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

这样的东西?也许我不知道企业库中的一些验证器?!

4 个答案:

答案 0 :(得分:5)

您可以在setter逻辑中进行验证。

编辑:一些例子:

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

答案 1 :(得分:0)

你可以这样做一个解决方法:

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

答案 2 :(得分:0)

与st4hoo的解决方案相同,只有反射。你可以像你想的那样疯狂。

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

答案 3 :(得分:0)

另一种解决方法是通过前端验证/过滤。我遇到了一个场景,在db级别上,我需要允许db将字段保存到任何枚举值,但我不希望最终用户看到无效选项。因此,我为枚举值创建了一个属性,指定哪种用户可以看到这些枚举值。

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

然后我用该属性修饰了枚举值。

public enum myEnum{

    ZeroValue,

    [Field(FilterProperty = 0)]
    FirstValue,

    [Field(FilterProperty = 1)]
    SecondValue,

    [Field(FilterProperty = 0)]
    ThirdValue,

    [Field(FilterProperty = 1)]
    FourthValue,
}

然后我创建了一个扩展方法,该方法只提供了用户可以看到的值的字典。

        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());

然后,当数据进入前端时,只要他们选择的是基本枚举的一部分,DB就可以保存它。

不是直接回答你的问题,而是间接的路线,可以帮助你获得你想要的东西。