我的应用程序定义了几个包含enum
属性的[Flags]
。
我想编写一个小实用程序方法来检查是否为这些enum
中的任何一个设置了标记,我想出了以下内容。
protected static bool IsFlagSet<T>(ref T value, ref T flags)
{
return ((value & flags) == flags);
}
但这给了我错误“操作员”&amp;'不能应用于'T'和'T'类型的操作数。
这可以起作用吗?
答案 0 :(得分:15)
Enum类已经有一个效用函数:Enum.HasFlag(Flag f)
,请参阅example on MSDN
if (petsInFamily.HasFlag(Pet.Dog))
familiesWithDog++;
注意:这是在C#4中引入的。 虽然它非常易读但可能会出现一些性能问题。
答案 1 :(得分:3)
我明白我的答案为时已晚,但我发现这个问题真的很神奇。
从.Net 4开始,我们可以在C#中使用dynamic
类型。你可以重写方法:
protected static bool IsFlagSet<T>(T value, T flags)
{
dynamic a = value;
dynamic b = flags;
return ((a & b) == flags);
}
dynamic
背后的想法允许您推迟到运行时,如果类型T
支持方法/运算符。因此,如果为&
定义T
,则运行时成功。
答案 2 :(得分:2)
&安培;是类类型的运算符。这意味着T类必须有一个重载运算符&amp;。
的方法.Net不能指望每个班级都会拥有它。所以它失败了。
你可以做的是创建一个基类,它将操作符重载声明为方法。
然后使用Constraints声明T使用该基类:
protected static bool IsFlagSet<T> where T: BaseclassWithAnd (ref T value, ref T flags)
{
return ((value & flags) == flags);
}
答案 3 :(得分:2)
您必须将其类型转换为定义&amp;的类型。操作
protected static bool IsFlagSet<T>(ref T value, ref T flags)
{
return ((Convert.ToInt32(value) & Convert.ToInt32(flags)) == Convert.ToInt32(flags));
}
答案 4 :(得分:2)
错误的原因是您不能将泛型类型限制为“为T,T定义了运算符X”。因此,C#必须假设没有为T,T定义的运算符X并显示错误。
这是与==运算符有关的行为 - 即Can't operator == be applied to generic types in C#?,但适用于所有运算符。
有关可能限制的完整列表,请参阅 - http://msdn.microsoft.com/en-us/library/d5x73970(v=VS.100).aspx,请注意Enum没有约束(对于您的场景特别有用),也没有定义运算符X的类型。