【问题标题】:Next or previous enum下一个或上一个枚举
【发布时间】:2009-01-10 00:34:29
【问题描述】:

给定一个已赋值的枚举,在给定值的情况下获取下一个或上一个枚举的最佳方法是什么。例如,考虑这个枚举:

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];
    }
}

【问题讨论】:

  • 这是在工作中使用错误工具的一个很好的例子——因此我赞成。感谢您发布一个好问题。 =)

标签: c# enums


【解决方案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"
   }

}

【讨论】:

  • 啊,这是一个更好的方法。该类长期以来一直是一个枚举,并且在添加新功能时,我尝试扩展而不是重构。谢谢你的打击:)
  • 只是想补充一下,还有一个 IComparable 接口供那些复制上面的代码示例的人使用,这样您就不必检查 CompareTo 的类型了。
【解决方案2】:

.NET 中的枚举并不是真正需要订购的,因此您不应该依赖它。稍后其他人可能会过来并在中间某处添加一个不正常的值。因此也没有内置这样的功能。您可以编写自己的函数(类似于您已经编写的函数),但这完全取决于您。我还建议您在您的方法中自己进行排序,而不是依赖 .NET 来保持项目“排序”。

补充:那个,我也赞同你应该选择其他数据结构的观点。

【讨论】:

    【解决方案3】:

    据我所知,没有内置的方法可以做到这一点,而且您的解决方案看起来很花哨 - 假设枚举是在这里使用的正确构造......

    我确实认为您正在尝试对枚举做一些事情。也许 TimeframeType 应该是一个类,还是应该有一个 Timeframe 数据的静态数组?

    (刚刚看到 Jimmy 的帖子 - 看起来我们有类似的看法)。

    【讨论】:

      【解决方案4】:

      请参阅问题Enum in C++ like Enum in Ada 以了解有关 Ada 所做的事情的信息 - 而且,尽管那里的 cmets 中有什么内容,但我认为在 C、C++ 或(我认为)在 C# 中提供相同的功能并不是一件容易的事或 Java,除非这些系统自动提供帮助。

      【讨论】:

        【解决方案5】:

        请注意,这仅在您不关心枚举的值并且只希望它们有序时才有效

        如果您可以更改枚举,我会执行以下操作

        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")]
        }
        

        然后我将通过 TimeFrameStep 递增增量器从 Now 循环到 Long。

        【讨论】:

          猜你喜欢
          • 2010-10-13
          • 1970-01-01
          • 2010-09-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-22
          相关资源
          最近更新 更多