Следующий или предыдущий перечисление
Учитывая перечисление, которое присвоено значениям, каков наилучший способ получить следующее или предыдущее перечисление с учетом значения. Например, рассмотрите это перечисление:
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
}
Есть ли хороший способ создать функцию, которая будет делать EnumPrevious (TimeframeType.Short), возвращает TimeframeType.Now и EnumNext (TimeframeType.Short) будут возвращать TimeframeType.Medium?
Я уже написал уродливую реализацию EnumNext, но я не уверен, что это лучший способ сделать это. Я надеюсь, что кто-то еще справится с этой проблемой.
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];
}
}
Ответы
Ответ 1
Вы пытаетесь решить неправильную проблему. Это слишком сложно для простого перечисления для вычисления. Рефакторинг перечисления для класса и использование интерфейса сравнения.
Если этот маршрут открыт для вас, посмотрите, как это может быть реализовано классом:
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"
}
}
Ответ 2
Перечисления в .NET на самом деле не предназначены для заказа, поэтому вы не должны полагаться на него. Кто-то еще позже может просто прийти и добавить значение где-то посередине, которое будет не в порядке. Таким образом, не существует такой встроенной функции. Вы можете написать свои собственные функции (похожие на то, что вы уже написали), но это полностью зависит от вас. Я также хотел бы, чтобы вы сортировали самостоятельно в своем методе и не полагались на .NET, чтобы сохранить "отсортированные" элементы.
Добавлено: Это, и я также высказываю мнение, что вы должны выбрать другую структуру данных.
Ответ 3
Насколько я знаю, для этого не существует встроенного способа, и ваше решение выглядит просто dandy - при условии, что enum - это правильная конструкция, которая будет использоваться здесь...
Я действительно думаю, что вы пытаетесь сделать многое с перечислением. Возможно, TimeframeType должен быть классом или должен быть статический массив данных Timeframe?
(только что увидел пост Джимми - похоже, что у нас есть аналогичное мнение).
Ответ 4
Обратите внимание, что это работает только если вы не заботитесь о значениях перечисления и просто хотите, чтобы они упорядочились
Если вы можете изменить enum, я бы сделал следующее
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")]
}
Затем я бы перебирал от Now to Long, увеличивая приращение с помощью TimeFrameStep.
Ответ 5
См. вопрос Перечислить на С++, например Enum в Ada для получения информации о том, что делает Ada, и, несмотря на то, что написано в комментариях, я не думаю, что это тривиальны, чтобы обеспечить ту же функциональность в C, С++, ни (я думаю) на С# или Java, если эти системы не предоставляют помощь автоматически.