HasFlag с общим перечислением?

Я только начинаю с Generics в С#, но на ранней стадии столкнулся с проблемой, как я могу вызвать .HasFlag() для общего Enum?

public class Example<TEnum> where TEnum : struct {
}

Как я могу добавить к нему атрибут [Flags]?

Ответ 1

Вызов метода экземпляра в любом случае потребует бокса, поэтому, поскольку вы не можете сдерживать Enum, просто отказаться от дженериков и использовать Enum. Например, вместо:

void Something(TEnum enumValue, TEnum flags)
{
    if (enumValue.HasFlags(flags))
        //do something ...
}

Сделайте это:

void Something(Enum enumValue, Enum flags)
{
    if (enumValue.HasFlags(flags))
        //do something ...
}

В универсальном методе вы можете достичь своей цели следующим образом:

void Something(TEnum enumValue, TEnum flags)
{
    Enum castValue = (Enum)(object)enumValue;
    Enum castFlags = (Enum)(object)flags;

    if (castValue.HasFlags(castFlags))
        //do something ...
}

Это вызовет исключение во время выполнения, если вы вызовете метод с типом значения, который не является перечислением. Вы также можете использовать ValueType вместо object, так как известно, что тип параметра представляет тип значения:

Enum castValue = (Enum)(ValueType)enumValue;