Как получить следующее (или предыдущее) значение перечисления в C # - PullRequest
47 голосов
/ 13 марта 2009

У меня есть перечисление, которое определяется так:

public enum eRat { A = 0, B=3, C=5, D=8 };

Итак, учитывая значение eRat.B, я хочу получить следующее, которое eRat.C

Решение, которое я вижу (без проверки диапазона)

Array a = Enum.GetValues(typeof(eRat));
int i=0 ;
for (i = 0; i < a.GetLength(); i++)
{
       if (a.GetValue(i) == eRat.B)
            break;
}
return (eRat)a.GetValue(i+1):

Теперь это слишком сложно, для чего-то такого простого. Знаете ли вы лучшее решение ?? Что-то вроде eRat.B+1 или Enum.Next(Erat.B)?

Спасибо

Ответы [ 22 ]

1 голос
/ 13 марта 2009

var next = (eRat) ((int) someRat + 3);

1 голос
/ 13 марта 2009

Для меня это выглядит как злоупотребление классом enum - но это бы сработало (при условии, что вызов Next для последнего значения вызовет циклическое изменение):

public static eRat Next(this eRat target)
{
    var nextValueQuery = Enum.GetValues(typeof(eRat)).Cast<eRat>().SkipWhile(e => e != target).Skip(1);
    if (nextValueQuery.Count() != 0)
    {
        return (eRat)nextValueQuery.First();
    }
    else
    {
        return eRat.A;
    }
}

И это даст вам предыдущее значение на той же основе:

public static eRat Previous(this eRat target)
{
    var nextValueQuery = Enum.GetValues(typeof(eRat)).Cast<eRat>().Reverse().SkipWhile(e => e != target).Skip(1);
    if (nextValueQuery.Count() != 0)
    {
        return (eRat)nextValueQuery.First();
    }
    else
    {
        return eRat.D;
    }
}
1 голос
/ 13 марта 2009

Я могу думать о 2 вещах:

  • eRat.B + 3
  • Enum.Parse (TypeOf (((ИНТ) eRat.B) +3)
1 голос
/ 15 октября 2014

Старый пост, но у меня есть альтернативное решение

//Next with looping    
public static Enum Next(this Enum input)
{
    Array Arr = Enum.GetValues(input.GetType());
    int j = Array.IndexOf(Arr, input) + 1;
    return (Arr.Length == j) ? (Enum)Arr.GetValue(0) : (Enum)Arr.GetValue(j);
}

//Previous with looping
public static Enum Prev(this Enum input)
{
   Array Arr = Enum.GetValues(input.GetType());
   int j = Array.IndexOf(Arr, input) - 1;
   return (j == -1) ? (Enum)Arr.GetValue(Arr.Length -1) : (Enum)Arr.GetValue(j);
}

И когда вам нужно его использовать, просто выполните приведение

BootstrapThemeEnum theme = BootstrapThemeEnum.Info;
var next = (BootstrapThemeEnum)theme.Next();

мое перечисление

public enum BootstrapThemeEnum
{
    [Description("white")]
    White = 0,
    [Description("default")]
    Default = 1,
    [Description("info")]
    Info = 2,
    [Description("primary")]
    Primary = 3,
    [Description("success")]
    Success = 4,
    [Description("warning")]
    Warning = 5,
    [Description("danger")]
    Danger = 6,
    [Description("inverse")]
    Inverse = 7

}
1 голос
/ 25 февраля 2016

Существует очень простое решение (если вы можете изменить целочисленные значения) , специально предназначенное для работы с числами. Тот факт, что ваш номер enum, не является проблемой. Это по-прежнему integer (или любой другой тип номера, который вы назначаете). Enum просто добавляет сложность к касту.

Предположим, ваш enum определен так:

 public enum ItemStatus
    {
        New = 0,
        Draft = 1,
        Received = 2,
        Review = 4,
        Rejected = 8,
        Approved = 16
    }

ItemStatus myStatus = ItemStatus.Draft;

Используйте побитовые операции на Enum. Например:

myStatus = (ItemStatus)(((int)myStatus) << 1)

Результат myStatus: ItemStatus.Received .

Вы также можете перейти назад Enum, изменив побитовый оператор с << на >>.

myStatus = (ItemStatus)(((int)myStatus) >> 1)

Результат myStatus: ItemStatus.New .

Вы всегда должны добавлять код для проверки ситуации "вне границ" в обоих направлениях.

Подробнее о побитовых операциях вы можете узнать здесь: http://code.tutsplus.com/articles/understanding-bitwise-operators--active-11301

1 голос
/ 15 июля 2013

Я использую это, идеально подходит для моего.

    //===================================================================================
// NEXT VALUE IN ENUM 
// ex: E_CamModes eNew =  kGlobalsVars.eGetNextValue< E_CamModes >( geCmMode );
public static T eGetNextValue< T >( T eIn ){
    T[] aiAllValues = ( T[] ) Enum.GetValues( typeof( T ));
    int iVal = System.Array.IndexOf( aiAllValues, eIn );
    return aiAllValues[ ( iVal + 1 ) % aiAllValues.Length ];
}
0 голосов
/ 07 мая 2019

Я сделал что-то похожее с другим enum. Это для игры, и у игрока есть возможность переключать цвета.

public enum PlayerColor {
    Red = 0, Green, Blue, Cyan, Yellow, Orange, Purple, Magenta
}

public PlayerColor GetNextFreeColor(PlayerColor oldColor) {

    PlayerColor newColor = (PlayerColor)((int)(oldColor + 1) % 8);
    return newColor;
}

Это решение сработало для меня.

0 голосов
/ 22 ноября 2018

Я попробовал первое решение, но оно у меня не сработало. Ниже мое решение:

    public  object NextEnumItem(object currentEnumItem) 
    {
        if (!currentEnumItem.GetType().IsEnum) throw new 
                ArgumentException(String.Format("Argument is not an Enum"));
        Array Arr = Enum.GetValues(currentEnumItem.GetType());
        int j = Array.IndexOf(Arr,currentEnumItem) + 1;
        return (Arr.Length == j) ? currentEnumItem : Arr.GetValue(j);
    }

    public object PreviousEnumItem(object currentEnumItem)
    {
        if (!currentEnumItem.GetType().IsEnum)
            throw new ArgumentException(String.Format("Argument is not an Enum"));
        Array Arr = Enum.GetValues(currentEnumItem.GetType());
        int j = Array.IndexOf(Arr, currentEnumItem) - 1;
        return (j==-1) ? currentEnumItem : Arr.GetValue(j);
    }
0 голосов
/ 18 ноября 2014

Решение LINQ, которое не прерывается на последнем элементе, но снова продолжается по умолчанию:

var nextValue = Enum.GetValues(typeof(EnumT)).Cast<EnumT>().Concat(new[]{default(EnumT)}).SkipWhile(_ => _ != value).Skip(1).First();
0 голосов
/ 18 июля 2014

Я использую это здесь:

public MyEnum getNext() {
    return this.ordinal() < MyEnum.values().length - 1 ? 
                            MyEnum.values()[this.ordinal() + 1] : 
                            MyEnum.values()[0];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...