当前位置:  开发笔记 > 编程语言 > 正文

如何在C#中获取下一个(或以前的)枚举值

如何解决《如何在C#中获取下一个(或以前的)枚举值》经验,为你挑选了5个好方法。

我有一个枚举,其定义如下:

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+1Enum.Next(Erat.B)

谢谢



1> husayt..:

感谢大家的回答和反馈.得到这么多人我感到很惊讶.看着他们并使用了一些想法,我想出了这个最适合我的解决方案:

public static class Extensions
{

    public static T Next(this T src) where T : struct
    {
        if (!typeof(T).IsEnum) throw new ArgumentException(String.Format("Argument {0} is not an Enum", typeof(T).FullName));

        T[] Arr = (T[])Enum.GetValues(src.GetType());
        int j = Array.IndexOf(Arr, src) + 1;
        return (Arr.Length==j) ? Arr[0] : Arr[j];            
    }
}

这种方法的优点在于它使用简单且通用.实现为通用扩展方法,您可以通过以下方式在任何枚举上调用它:

return eRat.B.Next();

注意,我使用的是通用扩展方法,因此我不需要在调用时指定类型.Next().



2> Marc Gravell..:

可能有点矫枉过正,但是:

eRat value = eRat.B;
eRat nextValue = Enum.GetValues(typeof(eRat)).Cast()
        .SkipWhile(e => e != value).Skip(1).First();

或者如果你想要第一个在数值上更大的东西:

eRat nextValue = Enum.GetValues(typeof(eRat)).Cast()
        .First(e => (int)e > (int)value);

或者对于下一个更大的数字(我们自己做):

eRat nextValue = Enum.GetValues(typeof(eRat)).Cast()
        .Where(e => (int)e > (int)value).OrderBy(e => e).First();

嘿,以LINQ为锤子,这个世界充满了指甲;-p


+1"用LINQ作为你的锤子" - >不伤害自己是最快的学习方法吗?;)
如果你已经在最后一个枚举,这会爆炸吗?

3> Kent Boogaar..:

真的需要概括这个问题吗?你能这样做吗?

public void SomeMethod(MyEnum myEnum)
{
    MyEnum? nextMyEnum = myEnum.Next();

    if (nextMyEnum.HasValue)
    {
        ...
    }
}

public static MyEnum? Next(this MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.A:
            return MyEnum.B;
        case MyEnum.B:
            return MyEnum.C;
        case MyEnum.C:
            return MyEnum.D;
        default:
            return null;
    }
}


-1.我不喜欢这样,因为这是一个等待发生的维护错误.你添加一些内容的那天,你想知道为什么你的代码返回null确实是糟糕的一天.
+1简单.建立解决眼前需求并继续前进的东西.如有必要,稍后重构.

4> Michael Mead..:

你正在处理的问题是因为你试图让枚举做一些不应该做的事情.它们应该是类型安全的.允许为枚举分配整数值,以便您可以组合它们,但如果您希望它们表示整数值,请使用类或结构.这是一个可能的替代方案:

public static class eRat
{
    public static readonly eRatValue A;
    public static readonly eRatValue B;
    public static readonly eRatValue C;
    public static readonly eRatValue D;

    static eRat()
    {
        D = new eRatValue(8, null);
        C = new eRatValue(5, D);
        B = new eRatValue(3, C);
        A = new eRatValue(0, B);
    }

    #region Nested type: ERatValue
    public class eRatValue
    {
        private readonly eRatValue next;
        private readonly int value;

        public eRatValue(int value, eRatValue next)
        {
            this.value = value;
            this.next = next;
        }

        public int Value
        {
            get { return value; }
        }

        public eRatValue Next
        {
            get { return next; }
        }

        public static implicit operator int(eRatValue eRatValue)
        {
            return eRatValue.Value;
        }
    }
    #endregion
}

这允许您这样做:

int something = eRat.A + eRat.B;

还有这个

eRat.eRatValue current = eRat.A;
while (current != null)
{
    Console.WriteLine(current.Value);
    current = current.Next;
}

当你可以从类型安全中受益时,你真的应该只使用枚举.如果您依赖它们来表示类型,请切换到常量或类.

编辑

我建议你看看Enumeration Design上的MSDN页面.第一个最佳做法是:

使用枚举来强类型化参数,属性和返回值,这些值表示值集.

我尽量不去争论教条,所以我不会,但这是你要面对的问题.Microsoft不希望您执行您要执行的操作.他们明确要求你不要做你想做的事.这使你很难做你想做的事情.为了完成您要做的事情,您必须构建实用程序代码以强制它看起来有效.

你已经叫你的解决方案优雅不止一次,它可能是,如果枚举被设计以不同的方式,但由于枚举是它们是什么,你的解决方案是不优雅.我认为室内音乐很优雅,但是如果音乐家没有合适的乐器并且不得不用锯片和水壶演奏Vivaldi,那么它将不再优雅,无论他们作为音乐家的能力如何,或音乐有多好在纸上.



5> dance2die..:

达到"C",因为在"D"之后没有回答什么.

[update1]:根据Marc Gravell的建议更新.

[update2]:根据husayt的需要更新 - 返回"A"代表下一个"D"值.

public class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Next enum of A = {0}", eRatEnumHelper.GetNextEnumValueOf(eRat.A));
        Console.WriteLine("Next enum of B = {0}", eRatEnumHelper.GetNextEnumValueOf(eRat.B));
        Console.WriteLine("Next enum of C = {0}", eRatEnumHelper.GetNextEnumValueOf(eRat.C));
    }
}

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

public class eRatEnumHelper
{
    public static eRat GetNextEnumValueOf(eRat value)
    {
        return (from eRat val in Enum.GetValues(typeof (eRat)) 
                where val > value 
                orderby val 
                select val).DefaultIfEmpty().First();
    }
}

结果

A = B的
下一个枚举B = C的
下一个枚举C = D的
下一个枚举D = A的下一个枚举

推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有