Reputation: 18792
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
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
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
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
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
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