Alex Rivera | Logout

C#: Enum.IsDefined on combined flags

Asked 2009-02-09T09:09:58.817
23

I have this enum:

[Flags]
public enum ExportFormat
{
    None = 0,
    Csv = 1,
    Tsv = 2,
    Excel = 4,
    All = Excel | Csv | Tsv
}

I am trying to make a wrapper on this (or any, really) enum which notifies on change. Currently it looks like this:

public class NotifyingEnum<T> : INotifyPropertyChanged
    where T : struct
{
    private T value;

    public event PropertyChangedEventHandler PropertyChanged;

    public NotifyingEnum()
    {
        if (!typeof (T).IsEnum)
            throw new ArgumentException("Type T must be an Enum");
    }

    public T Value
    {
        get { return value; }
        set
        {
            if (!Enum.IsDefined(typeof (T), value))
                throw new ArgumentOutOfRangeException("value", value, "Value not defined in enum, " + typeof (T).Name);

            if (!this.value.Equals(value))
            {
                this.value = value;

                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs("Value"));
            }
        }
    }
}

Since an enum can be assigned with any value really, I want to check if the given Value is defined. But I found a problem. If I here give it an enum consisting of for example Csv | Excel, then Enum.IsDefined will return false. Apparently because I haven't defined any enum consisting of those two. I guess that on some level is logical, but how should I then check if the given value is valid? In other words, to make it work, what do I need to swap this following line with?

if (!Enum.IsDefined(typeof (T), value))
Edit
Report

1 Answer

15

We know that an enum value converted to a string will never start with a digit, but one that has an invalid value always will. Here's the simplest solution:

public static bool IsDefinedEx(this Enum yourEnum)
{
    char firstDigit = yourEnum.ToString()[0];
    if (Char.IsDigit(firstDigit) || firstDigit == '-')  // Account for signed enums too..
        return false;

    return true;
}

Use that extension method instead of the stock IsDefined and that should solve your issue.

answered 2012-01-12T00:01:49.683

Your Answer