我的应用程序定义了几个enum
包含该[Flags]
属性的 s。
我想编写一个小的实用程序方法来检查是否为其中任何一个设置了标志enum
,我想出了以下内容。
protected static bool IsFlagSet<T>(ref T value, ref T flags)
{
return ((value & flags) == flags);
}
但这给了我错误“运算符'&'不能应用于'T'和'T'类型的操作数”。
这可以工作吗?
我的应用程序定义了几个enum
包含该[Flags]
属性的 s。
我想编写一个小的实用程序方法来检查是否为其中任何一个设置了标志enum
,我想出了以下内容。
protected static bool IsFlagSet<T>(ref T value, ref T flags)
{
return ((value & flags) == flags);
}
但这给了我错误“运算符'&'不能应用于'T'和'T'类型的操作数”。
这可以工作吗?
Enum 类已经有一个实用函数:Enum.HasFlag(Flag f)
,见MSDN 上的例子
if (petsInFamily.HasFlag(Pet.Dog))
familiesWithDog++;
注意:这是在 C# 4 中引入的。虽然它非常易读,但可能存在一些性能问题。
我知道我的回答为时已晚,但我发现这个问题的解决方案非常棒。从 .Net 4 开始,我们可以dynamic
在 C# 中使用类型。您的方法可以重写:
protected static bool IsFlagSet<T>(T value, T flags)
{
dynamic a = value;
dynamic b = flags;
return ((a & b) == flags);
}
dynamic
如果 type 支持方法/运算符,则其背后的想法允许您推迟到运行时T
。因此,如果&
定义为T
然后运行时成功。
& 是类类型的运算符。这意味着类 T 必须有一个重载运算符 & 的方法。
.Net 不能指望每个班级都会有它。所以它失败了。
您可以做的是创建一个基类,将运算符重载声明为方法。
然后使用Constraints声明 T 使用该基类:
protected static bool IsFlagSet<T> where T: BaseclassWithAnd (ref T value, ref T flags)
{
return ((value & flags) == flags);
}
您必须将其类型转换为定义 & 操作的类型。
protected static bool IsFlagSet<T>(ref T value, ref T flags)
{
return ((Convert.ToInt32(value) & Convert.ToInt32(flags)) == Convert.ToInt32(flags));
}
The reason of the error is that you can't restric generic type as "have operator X defined for T,T". As result C# has to assume that there is no operator X defined for T,T and shows an error.
This is behavior often discussed in relation to == operator - i.e. Can't operator == be applied to generic types in C#?, but applies to all operators.
For full list of possible constrints see - http://msdn.microsoft.com/en-us/library/d5x73970(v=VS.100).aspx, note that there is no constraint for Enum (that would be useful for your scenario specifically) nor for types with operator X defined.