开发者

Operator '&' cannot be applied to operands of type 'T' and 'T' [duplicate]

This question already has answers here: C#, Flags Enum, Generic function to look for a flag (11 answers) Closed 6 years ago.

My application defines several enums that include the [Flags] attribute.

I wanted to write a small utility method to check if a flag was set for any of those enums and I came up with the following.

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

But this gives me the error "Operator '&' cannot be appl开发者_StackOverflow社区ied to operands of type 'T' and 'T'".

Can this be made to work?


The Enum class already has a utility function: Enum.HasFlag(Flag f), see the example on MSDN

 if (petsInFamily.HasFlag(Pet.Dog))
        familiesWithDog++;

Note: This was introduced in C# 4. And while it's very readable it may have some performance issues.


I understand that my answer is too late, but I found really amazing solution of this problem. Starting from .Net 4 we can use dynamic types in C#. You method can be rewritten:

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

Idea behind that dynamic allows you postpone to runtime if method/operator supported by type T. So if & is defined for T then runtime is success.


& is an operator on a class type. Which means that the class T has to have a method that overloads the operator &.

.Net can't expect that every class will have it. So it fails.

What you can do, is make a base class, that declares the operator overload as a method.

Then use Constraints to declare that T uses that base class:

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


You must type-cast it to a type that defines the & operation.

    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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜