代码之家  ›  专栏  ›  技术社区  ›  Sunny

带标志属性的枚举.tryparse

  •  15
  • Sunny  · 技术社区  · 15 年前

    我写了代码给 TryParse 按值或按其名称枚举,如下所示。如何扩展此代码以包含对枚举的解析 Flags 属性?

        public static bool TryParse<T>(this T enum_type, object value, out T result) 
                    where T : struct
                {
                    return enum_type.TryParse<T>(value, true, out result);
                }
    
    
    
     public static bool TryParse<T>(this T enum_type, 
    object value, bool ignoreCase, out T result)
            where T : struct
        {
            result = default(T);
            var is_converted = false;
    
            var is_valid_value_for_conversion = new Func<T, object, bool, bool>[]{
                (e, v, i) => e.GetType().IsEnum,
                (e, v, i) => v != null,
                (e, v, i) => Enum.GetNames(e.GetType()).Any(n => String.Compare(n, v.ToString(), i) == 0) || Enum.IsDefined(e.GetType(), v)
            };
    
            if(is_valid_value_for_conversion.All(rule => rule(enum_type, value, ignoreCase))){
                result = (T)Enum.Parse(typeof(T), value.ToString(), ignoreCase);
                is_converted = true;
            }
    
            return is_converted;
        }
    

    当前,此代码适用于以下枚举:

    enum SomeEnum{ A, B, C } 
    // can parse either by 'A' or 'a'
    
    enum SomeEnum1 : int { A = 1, B = 2, C = 3 } 
    // can parse either by 'A' or 'a' or 1 or "1"
    

    不适用于:

    [Flags]
    enum SomeEnum2 { A = 1, B = 2, C = 4 } // can parse either by 'A' or 'a'
    // cannot parse for A|B
    

    谢谢!

    3 回复  |  直到 7 年前
        1
  •  31
  •   Pop Catalin    15 年前

    使用 , 通过使用.NET约定而不是 | . 当使用“,”字符串时,enum.parse()工作得很好:

    [Flags]
    public enum Flags
    {
        A = 1,
        B = 2,
        C = 4,
        D = 8,
    }
    
    var enumString =  (Flags.A | Flags.B | Flags.C).ToString();
    Console.WriteLine(enumString); // Outputs: A, B, C
    Flags f = (Flags)Enum.Parse(typeof(Flags),  enumString);
    Console.WriteLine(f); // Outputs: A, B, C
    
        2
  •  17
  •   dtb    15 年前

    从.net 4开始,有一个 Enum.TryParse<T> 方法。它支持 旗帜 开箱即用的枚举:

    string x = (SomeEnum2.A | SomeEnum2.B).ToString();  //  x == "A, B"
    SomeEnum2 y;
    bool success = Enum.TryParse<SomeEnum2>(x, out y);  //  y == A|B
    
        3
  •  0
  •   Sunny    15 年前

    @pop的回答给了我一个线索&我修改了代码中的规则签入,使其看起来像:

    var is_valid_value_for_conversion = new Func<T, object, bool, bool>[]
    {
        (e, v, i) => e.GetType().IsEnum,
        (e, v, i) => value != null,
        (e, v, i) => Enum.GetNames(e.GetType()).Any(
                    n => String.Compare(n, v.ToString(), i) == 0 
                    || (v.ToString().Contains(",") && v.ToString().ToLower().Contains(n.ToLower()))) 
                    || Enum.IsDefined(e.GetType(), v)
    };
    

    其余的都是一样的,对我有用

    还有其他人