Generic extension method to see if an enum contains a flag

前端 未结 8 1098
闹比i
闹比i 2021-02-01 01:56

Considering this:

[Flags]
public enum MyEnum {
    One = 1,
    Two = 2,
    Four = 4,
    Eight = 8
}

public static class FlagsHelper
{
    public static bool          


        
相关标签:
8条回答
  • 2021-02-01 02:43

    Another way of implementing HasFlag function for the .NET Framework 3.5.

    public static bool HasFlag(this Enum e, Enum flag)
    {
        // Check whether the flag was given
        if (flag == null)
        {
            throw new ArgumentNullException("flag");
        }
    
        // Compare the types of both enumerations
        if (e.GetType() != (flag.GetType()))
        {
            throw new ArgumentException(string.Format(
                "The type of the given flag is not of type {0}", e.GetType()),
                "flag");
        }
    
        // Get the type code of the enumeration
        var typeCode = e.GetTypeCode();
    
        // If the underlying type of the flag is signed
        if (typeCode == TypeCode.SByte || typeCode == TypeCode.Int16 || typeCode == TypeCode.Int32 ||
            typeCode == TypeCode.Int64)
        {
            return (Convert.ToInt64(e) & Convert.ToInt64(flag)) != 0;
        }
    
        // If the underlying type of the flag is unsigned
        if (typeCode == TypeCode.Byte || typeCode == TypeCode.UInt16 || typeCode == TypeCode.UInt32 ||
            typeCode == TypeCode.UInt64)
        {
            return (Convert.ToUInt64(e) & Convert.ToUInt64(flag)) != 0;
        }
    
        // Unsupported flag type
        throw new Exception(string.Format("The comparison of the type {0} is not implemented.", e.GetType().Name));
    }
    

    This extension method supports all the possible types for an enumeration (byte, sbyte, short, ushort, int, uint, long and ulong). Basically, the method checks if the given enumeration is signed/unsigned and converts the flag to the type with the highest size of the supported types for an enumeration. Then, a simple comparison is performed using the & operator.

    As explained in other posts, we cannot define a constraint of the generic type with an enumeration and it doesn't make sense to use generic with a struct constraint, because w developers could insert other enumerations types or structures then. So, I think it's better to not use generic method for that.

    0 讨论(0)
  • 2021-02-01 02:45

    This is an example of something that should work.

    public static bool IsValid<T>(this T value)
    {
        return Enum.IsDefined(value.GetType(), value);
    }
    
    0 讨论(0)
提交回复
热议问题