运营商'&'不能应用于'T'和'T'类型的操作数

时间:2011-05-08 18:07:28

标签: c# generics generic-method

我的应用程序定义了几个包含enum属性的[Flags]

我想编写一个小实用程序方法来检查是否为这些enum中的任何一个设置了标记,我想出了以下内容。

protected static bool IsFlagSet<T>(ref T value, ref T flags)
{
    return ((value & flags) == flags);
}

但这给了我错误“操作员”&amp;'不能应用于'T'和'T'类型的操作数。

这可以起作用吗?

5 个答案:

答案 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的类型。