【问题标题】:Specify allowed enum values in a property在属性中指定允许的枚举值
【发布时间】:2014-05-15 13:03:11
【问题描述】:

是否可以指定一个枚举属性只能有一个值范围?

enum Type
{
    None,
    One,
    Two,
    Three
}

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

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

【问题讨论】:

  • 这违背了枚举的全部目的。它是允许值的集合。
  • 一个枚举应该是允许值的范围。
  • ...你永远不想将其限制为特定属性的子集,伙计们?
  • 不,我会创建第二个(或第三个)枚举。 @rawling
  • @CodyGray 但这会导致不同类型的值实例,这可能非常不方便。

标签: c# enums enterprise-library validation


【解决方案1】:

您可以在 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;
        }
    }
}

【讨论】:

  • 我支持这个,在将其写入支持字段之前,您可以添加一些验证。这确实回答了这个问题,但我不推荐这样的逻辑......
  • @MrMichael 你会推荐什么?
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

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

      不是直接回答你的问题,而是一条间接的途径,可以帮助你得到你想要的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-11
        • 2021-08-30
        相关资源
        最近更新 更多