【问题标题】:Constraints on Type Parameters for flags and |= operator标志和 |= 运算符的类型参数约束
【发布时间】:2016-02-22 10:11:42
【问题描述】:

我有枚举,由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'

我该如何解决?

【问题讨论】:

  • 作为Enum 类型的扩展方法,而不是泛型方法,这会更好吗?
  • 完全同意@JamesThorpe 如果你限制泛型参数的类型,那么你应该停下来想想为什么你的方法应该是泛型的
  • 如何将T 类型限制为枚举,由Flags 属性标记?
  • @AndreyBushman 您不需要限制,因为它将是枚举的扩展方法,而不是泛型类型T
  • 相关但不重复:Is it possible to create a generic bitwise enumeration 'IsOptionSet()' method? 那里的答案应该允许您回答自己的问题。

标签: c# .net enums


【解决方案1】:

不清楚你想获得什么,但是,使用一点 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多