Оператор '&' не может быть применен к операндам типа 'T' и 'T'

Мое приложение определяет несколько enumы, которые включают в себя [Flags] приписывать.

Я хотел написать небольшой служебный метод, чтобы проверить, был ли установлен флаг для любого из этих enumи я придумал следующее.

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

Но это дает мне ошибку "Оператор" & "не может быть применен к операндам типа" T "и" T "".

Можно ли заставить это работать?

5 ответов

Решение

& является оператором типа класса. Это означает, что класс T должен иметь метод, который перегружает оператор &.

.Net не может ожидать, что у каждого класса будет это. Так что не получается.

Что вы можете сделать, так это создать базовый класс, который объявляет перегрузку оператора как метод.

Затем используйте Constraints, чтобы объявить, что T использует этот базовый класс:

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

Класс 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 позволяет отложить до времени выполнения, если метод / оператор поддерживается типом T, Так что если & определяется для T тогда время выполнения - это успех.

Причиной ошибки является то, что вы не можете ограничить универсальный тип как "иметь оператор X, определенный для T, T". В результате C# должен предположить, что не существует оператора X, определенного для T, T, и показывает ошибку.

Такое поведение часто обсуждается в связи с оператором == - т. Е. Нельзя ли применить оператор == к универсальным типам в C#?, но относится ко всем операторам.

Полный список возможных ограничений см. По адресу - http://msdn.microsoft.com/en-us/library/d5x73970(v=VS.100).aspx, обратите внимание, что для Enum нет ограничений (это было бы полезно для сценарий), а также для типов с определенным оператором X.

Вы должны привести его к типу, который определяет операцию &.

    protected static bool IsFlagSet<T>(ref T value, ref T flags)
    {
        return ((Convert.ToInt32(value) & Convert.ToInt32(flags)) == Convert.ToInt32(flags));
    }
Другие вопросы по тегам