Проверьте, установлено ли более одного флага в общем расширении

Заимствуя код из этого вопроса Как сделать Я проверяю, установлено ли более одного флага перечисления? Я попытался реализовать универсальное расширение, которое выполняет этот тест.

Моя первая попытка заключалась в следующем.

public static bool ExactlyOneFlagSet(this Enum enumValue)
{
    return !((enumValue & (enumValue - 1)) != 0);
}

Что привело к

Оператор «-» нельзя применять к операндам типа «System.Enum» и «int».

Хорошо, логично, поэтому я подумал, что попробую что-то вроде этого.

public static bool ExactlyOneFlagSet<T>(this T enumValue) where T : struct, IConvertible
{
    return !(((int)enumValue & ((int)enumValue - 1)) != 0);
}

Что привело к

Невозможно преобразовать тип «T» в «int»

Что также имеет смысл после прочтения об этом поведении, но тогда как этот метод расширения может быть реализован. Есть любезный помочь???


person Maxim Gershkovich    schedule 16.11.2012    source источник


Ответы (1)


Поскольку вы запрещаете T реализовывать IConvertible, вы можете просто вызвать ToInt32:

public static bool ExactlyOneFlagSet<T>(this T enumValue)
    where T : struct, IConvertible
{
    int v = enumValue.ToInt32(null);
    return (v & (v - 1)) == 0;
}
person dtb    schedule 16.11.2012
comment
Похоже, вам нужно обеспечить культуру! int v = enumValue.ToInt32(System.Threading.Thread.CurrentThread.CurrentCulture); Я ошибся? В остальном выглядит красиво, сейчас тестирую - person Maxim Gershkovich; 16.11.2012