DavGarcia
DavGarcia

Reputation: 18792

Next or previous enum

Given an enum that has assigned values, what is the best way to get the next or previous enum given a value. For example, consider this enum:

public enum TimeframeType {
    None = 0,
    [Description("1 month")]
    Now = 30,
    [Description("1-3 months")]
    Short = 90,
    [Description("3-6 months")]
    Medium = 180,
    [Description("6+ months")]
    Long = 360
}

Is there a good way create a function that would do EnumPrevious(TimeframeType.Short) returns TimeframeType.Now and EnumNext(TimeframeType.Short) would return TimeframeType.Medium?

I already wrote an ugly implementation of EnumNext but I'm not convinced that it is the best way to do so. I'm hoping someone else has already tackled this problem.

public static T EnumNext<T>(T value) where T : struct {
    T[] values = (T[])Enum.GetValues(typeof(T));

    int i;
    for (i = 0; i < values.Length; i++) {
        if (object.Equals(value, values[i])) {
            break;
        }
    }
    if (i >= values.Length - 1) {
        return values[values.Length - 1];
    } else {
        return values[i + 1];
    }
}

Upvotes: 4

Views: 4727

Answers (5)

hhafez
hhafez

Reputation: 39750

Note this only works if you don't care about the values of the enum and just want them ordered

If you can do change the enum I would do the following

public enum TimeframeType {
    None = 0,
    [Description("1 month")]

    TimeFrameStep = 30,
    [Description("Step from previous to next")]

    Now = None + TimeFrameStep,
    [Description("1-3 months")]
    
    Short = Now + TimeFrameStep,
    [Description("3-6 months")]

    Medium = Now + TimeFrameStep,
    [Description("6+ months")]
    
    Long = Medium + TimeFrameStep,
    [Description("12 months")]
}

Then I would loop from Now to Long by incrementing the incrementer by TimeFrameStep.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753605

See the question Enum in C++ like Enum in Ada for information on what Ada does - and, despite what's written in comments there, I don't think it is trivial to provide the same functionality in C, C++, nor (I think) in C# or Java unless those systems provide the help automatically.

Upvotes: 0

Jimmy McNulty
Jimmy McNulty

Reputation: 370

You are trying to solve the wrong problem. This is far too complex for a simple enum to calculate. Refactor the enum to a class and use a comparison interface.

If this route is open to you look at how this could be implemented by a class:

public class TimeFrame: IComparable
{
   private int days;

   public int Days
   {
        set 
        {
             days = value;
        }
   }

   public int CompareTo(object other)
   {
        //see this for implementation -- http://msdn.microsoft.com/en-us/library/system.icomparable.aspx#Mtps_DropDownFilterText
   }


   public string Description
   {
       get code to return the description string , ie "1-3 months"
   }

}

Upvotes: 5

Daniel Paull
Daniel Paull

Reputation: 6843

As far as I know, there is not built in way to do this, and your solution looks just dandy - assuming that an enum is the right construct to use here...

I do think that you're trying to do a bit to much with an enum. Perhaps TimeframeType should be a class or should there be a static array of Timeframe data?

(just saw Jimmy's post - looks like we have a similar opinion).

Upvotes: 0

Vilx-
Vilx-

Reputation: 106912

Enums in .NET aren't really meant to be ordered, so you shouldn't rely on it. Someone else later might just come and add a value somewhere in the middle that would be out of order. Thus there also isn't such a functionality built in. You can write your own functions (similar to what you have already written) but that's completely up to you. I would also adivse you do the sorting by yourself in your method and not rely on .NET to keep the items "sorted".

Added: That, and I also second the opinion that you should choose another data structure.

Upvotes: 2

Related Questions