Reputation: 1324
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'
Upvotes: 0
Views: 1392
Reputation: 1
An Enum can be one of: byte, sbyte, short, ushort, int, uint, long, or ulong value. To support all of these for your case, i wrote down a code that you can investigate. This is the limitation of Enum and solutions may differ. Some of the developers use IConvertible due to GetTypeCode() method which returns the underlying type of the value and Enum already implements that. This method returns TypeCode enum which tells a built-in type.
Upvotes: 0
Reputation: 2453
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;
}
}
Upvotes: 0
Reputation: 3733
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;
}
}
Upvotes: 1
Reputation: 7984
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;
}
}
Upvotes: 5