CleanCoder
CleanCoder

Reputation: 2867

Compare Enum for 0 default

This does not work. Even if source is 0, Equals to 0 will be false. How can it be achieved?

public static class EnumExtensions
{
    public static string ToFlagsString(this Enum source) => 
        Equals(source, 0) ? Resources.None : source.ToString();
}

The result of this method is something like

for an Enum variable which contains a enum value ""OptionA | OptionB" the result of this method would be "OptionA, OptionB"

public interface IOptions
{
    Enum Region { get; }
    Enum Flags { get; set; }
}

[Flags]
public enum ComparisonFlags : uint
{
    NonGameBuffer   = 1 << 0,
    WholeGameBuffer = 1 << 1,
    GameChecksum        = 1 << 2,
    AllGameChecksums    = 1 << 3 | GameChecksum,
    Unknown12B      = 1 << 4,
    AllUnknown12Bs  = 1 << 5 | Unknown12B,
}

usage:

PrintValue(options.Flags.ToFlagsString());

Update 1: I simplified the methd in replacing generic constraint by using "this System.Enum source"

Equals((uint)(object)source, 0) 

doesn't work either. (Update: it needs to be Equals((uint)(object)source, 0U))

How can this be changed to be used for all types of enums? not only for uint.

Update 2: It turned out that this works for all enum types passed as boxed System.Enum

public static string ToFlagsString(this Enum source)
{
    var enumType = source.GetType();
    var typeDefault = Convert.ChangeType(0, Enum.GetUnderlyingType(enumType));
    var enumDefault = Enum.ToObject(enumType, typeDefault);
    
    return Equals(source, enumDefault)? Resources.None : source.ToString();
}

this also works

public static string ToFlagsString(this Enum source) => source.ToString() == "0" ? Resources.None : source.ToString();

Update 3 Thanks to a comment from jeroen-mostert

public static string ToFlagsString(this Enum source) => source.Equals(Enum.ToObject(source.GetType(), 0)) ? Resources.None : source.ToString(); 

Upvotes: 1

Views: 117

Answers (2)

Gy&#246;rgy Kőszeg
Gy&#246;rgy Kőszeg

Reputation: 18013

Equals(source, 0) does not work because the arguments have different types.

Equals((uint)(object)source, 0) works only if the underlying enum type is uint; otherwise, you will get an InvalidCastException

You can treat your value as an IConvertible though: Equals(((IConvertible)source).ToInt64(null), 0L)

Of course to support any possible underlying types you need to be a bit more precise. Here is how you can convert any enum to ulong, for example.

Upvotes: 2

CleanCoder
CleanCoder

Reputation: 2867

I got it to work in a general way

public static string ToFlagsString(this Enum source)
    {
        var enumType = source.GetType();
        var typeDefault = Convert.ChangeType(0, Enum.GetUnderlyingType(enumType));
        var enumDefault = Enum.ToObject(enumType, typeDefault);
        
        return Equals(source, enumDefault)? Resources.None : source.ToString();
    }

Upvotes: 1

Related Questions