代码之家  ›  专栏  ›  技术社区  ›  Andrey Bushman

标志和|=运算符的类型参数约束

  •  0
  • Andrey Bushman  · 技术社区  · 9 年前

    我有枚举,标记为 Flags 属性枚举包含客户选择的变量。在控制台窗口中,用户可以指向单个变量,也可以指向用逗号分隔的一组必要变量(数字)。我的方法解析客户选择并将其转换为枚举值(标志集)。

    我还有一组类似的枚举。所以,我想对我的枚举集使用相同的代码。我不想复制相同的代码,因此我将其放在泛型方法中:

    private static T GetVariants<T>() where T : struct, IConvertible 
    {
        if (!typeof(T).IsEnum) {
            throw new ArgumentException("'T' must be an enumerated type.");
        }
        Dictionary<int, T> dict = new Dictionary<int, T>();
        // ...
        T cs = dict[0];
        // ...
        cs |= dict[n]; // Here is CS0019 error.
    }
    

    我得到编译错误:

    错误CS0019: 运算符“|=”不能应用于“T”类型的操作数 和“T”

    我该如何解决?

    1 回复  |  直到 9 年前
        1
  •  1
  •   xanatos    9 年前

    不清楚你想得到什么,但是,用一点 Expression 树:

    public static class Or<T>
    {
        public static readonly Func<T, T, T> Do;
    
        static Or()
        {
            var par1 = Expression.Parameter(typeof(T));
            var par2 = Expression.Parameter(typeof(T));
    
            Expression or;
    
            if (typeof(T).IsEnum)
            {
                Type type = Enum.GetUnderlyingType(typeof(T));
                or = Expression.Convert(
                    Expression.Or(
                        Expression.Convert(par1, type), 
                        Expression.Convert(par2, type)), 
                    typeof(T));
            }
            else
            {
                or = Expression.Or(par1, par2);
            }
    
            Do = Expression.Lambda<Func<T, T, T>>(or, par1, par2).Compile();
        }
    }
    

    您使用的代码如下:

    [Flags]
    public enum MyEnum
    {
        Val1 = 1,
        Val2 = 2,
        Val3 = 4,
    }
    
    public static T OrTogether<T>()
    {
        T ret = default(T);
    
        foreach (T val in (T[])Enum.GetValues(typeof(T)))
        {
            ret = Or<T>.Do(ret, val);
        }
    
        return ret;
    }