I would like compare two flags and see if they have any common value.
I'ld like having an extension method as weel in order to "speed up" coding (I'm going to use it often and on various Enum types). How can I?
This code tell me:
operator '&' cannot be applied to operands of type enum and enum
public enum Tag
{
Value1 = 1,
Value2 = 2,
Value3 = 4,
Value4 = 8,
Value5 = 16
}
public static class FlagExt
{
public static bool HasAny(this Enum me, Enum other)
{
return (me & other) != 0;
}
}
public class Program
{
public static void Main()
{
Tag flag1 = Tag.Value1 | Tag.Value2 | Tag.Value3;
Tag flag2 = Tag.Value2 | Tag.Value3 | Tag.Value4;
Console.WriteLine(flag1.HasAny(flag2)); // it should returns true. flag1.HasFlag(flag2) returns false.
}
}
I tried this as well:
return (((int)me) & ((int)other)) != 0;
but it raises the error:
Cannot convert type 'System.Enum' to 'int'
CodePudding user response:
As per this answer (How to convert from System.Enum to base integer?)
You will need to wrap this code with an exception handler or otherwise ensure that both enums hold an integer.
public static class FlagExt
{
public static bool HasAny(this Enum me, Enum other)
{
return (Convert.ToInt32(me) & Convert.ToInt32(other)) != 0;
}
}
CodePudding user response:
If you want a very generic HasAny
extension for enums you could do the following. I've tested that this works with all the different underlying types that an enum can be. Also, if you are checking for flags you should probably have the [Flags]
attribute decorating your enum, so this checks that the enums being checked have that attribute.
public static class FlagExtensions
{
public static bool HasAny(this Enum enumLeft, Enum enumRight)
{
if (enumLeft.GetType() != enumRight.GetType())
throw new ArgumentException("enum types should be the same");
if (!enumLeft.GetType().IsDefined(typeof(FlagsAttribute), inherit: false))
throw new ArgumentException("enum type should have the flags attribute");
dynamic enumLeftValue = Convert.ChangeType(enumLeft, enumLeft.GetTypeCode());
dynamic enumRightValue = Convert.ChangeType(enumRight, enumRight.GetTypeCode());
return (enumLeftValue & enumRightValue) != 0;
}
}
CodePudding user response:
I tried this as well:
return (((int)me) & ((int)other)) != 0;
but it raises the error:
Cannot convert type 'System.Enum' to 'int'
Enums always implement IConvertible and IConvertible has 'ToInt32'. So you could write it like this:
public static class FlagExt
{
public static bool HasAny<TEnum>(this TEnum me, TEnum other)
where TEnum : Enum, IConvertible
{
return (me.ToInt32(null) & other.ToInt32(null)) != 0;
}
}