【发布时间】:2018-10-25 19:39:13
【问题描述】:
编辑:这篇文章不是重复的,其他解决方案不能让我使用按位运算符。
我想做这样的事情:
public static class EnumExt
{
public static enum AddFlag(this enum e, enum flag) => e |= flag;
}
所以我可以这样使用它:
Color color = Red;
color.AddFlag(Color.Dark);
它只是更容易阅读。 我希望这个单一方法适用于所有枚举值,而不是为我计划使用的每个值进行覆盖。问题是,该代码不起作用,因为 enum 不是像int 这样的类型是。我尝试用泛型做一些事情:
public static class EnumExt
{
public static T AddFlag<T>(this T e, T flag)
where T : Enum // Can't constrain to Enum
{
return e = e | flag;
}
}
还有这个:
public static T AddFlag<T>(this T e, T flag)
where T : struct
{
if (!(typeof(T).IsEnum)) return default;
return e |= flag; // Operator '|' cannot be applied to T
}
这有两个问题。因为它是struct,这意味着此方法将显示int 值。我使用struct 只是因为它是最接近Enum 的约束。如果它不是Enum,我将退出该方法,但这仍然不会让编译器知道e 是enum,即使它应该始终在这一点上。
还尝试使用where T : int 和使用强制转换,但int 是无效约束。
有没有办法做到这一点?
编辑:我已经尝试了两个建议作为解决问题的答案,但它们没有。带有IEnumConstraint 的那个不起作用,因为它说我的enum 没有从它继承,而且两个答案都不允许我实际执行return e |= flag;
// Doesn't work because C# won't allow bitwise operators on generic types
// Because the constraint is still vague enough for non-enum values to slip through
public static T AddFlag<T>(this T e, T flag)
where T : struct, IConvertible
// Doesn't work because enums don't inherit from IEnumConstraint
// Same as above
public static T AddFlag<T>(this T e, T flag)
where T : struct, IEnumConstraint
我的猜测是,即使这些确实仅限于 Enum 值,其他一些类仍然有可能从 IEnumConstraint 和 IConvertible 继承,因此按位运算符将不起作用,因为它仍然不是保证操作将可用于T。
似乎唯一真正的解决方案是在 C# 7.3 中,它们允许您使用 System.Enum 作为约束。
【问题讨论】:
-
你安装的是什么版本的VS 2017?是最新的预览版吗?
标签: c# generics enums constraints extension-methods