枚举的范围是多少?

例如,在C#中,您可以在枚举类型中使用数字范围吗?

public enum BookType { Novel = 1, Journal = 2, Reference = 3, TextBook = 4 .. 10 } 

编辑:需要的原因是从数字转换为枚举类型,例如:

 int iBook = 5 BookType btBook = (BookType)ibook Debug.Print "Book " + ibook + " is a " btBook 

预期的输出是:第5册是一本教科书

根据C#标准(p612,C#编程语言),给定枚举的值必须是一个常量整数(或任何类似的类型 – 长,字节,字节,短等),因此一系列值无效。

我的编译器(VS2008)同意该规范。

由于您无法在枚举中重复名称,因此您最接近的名称是这样的:

 public enum BookType { Novel = 1, Journal = 2, Reference = 3, TextBook4 = 4, TextBook5 = 5, ... TextBook10 = 10 } 

这其实非常难看。 也许枚举不是你特定问题的解决方案……

正如其他人所说的那样,不可能。 如果它们是标志,则可以组合枚举值:

 [Flags] public enum BookType { Novel = 0, Journal = 1 << 0, Reference = 1 << 1, TextBook1 = 1 << 2, TextBook2 = 1 << 3, TextBook3 = 1 << 4, TextBook4 = 1 << 5, TextBook5 = 1 << 6, TextBooks1To5 = TextBook1 | TextBook2 | TextBook3 | TextBook4 | TextBook5 } 

由于您无法为枚举指定值范围,因此我想到了另一种方法,以便将枚举指定为限制值(示例基于时间):

  private enum eTiming { eOnTime = 0, eSlightDelay = 5, eMinorDelay = 15, eDelayed = 30, eMajorDelay = 45, eSevereDelay = 60 } private static eTiming CheckIfTimeDelayed(TimeSpan tsTime) { eTiming etiming = eTiming.eOnTime; foreach (eTiming eT in Enum.GetValues(typeof(eTiming))) { if (Convert.ToInt16(eT) <= tsTime.TotalMinutes) etiming = eT; } return etiming; } 

这假设enum已排序,并且使用带符号( - )值意外地工作。

有点偏离,您可以使用具有只读字段的普通类来模拟枚举。

例如,similair可以解决您的问题:

 public sealed class BookType { public static readonly BookType Novel = new BookType(1, 1, "Novel"); public static readonly BookType Journal = new BookType(2, 2, "Journal"); public static readonly BookType Reference = new BookType(3, 3, "Reference"); public static readonly BookType Textbook = new BookType(4, 10, "Textbook"); public int Low { get; private set; } public int High { get; private set; } private string name; private static class BookTypeLookup { public static readonly Dictionary lookup = new Dictionary(); } private BookType(int low, int high, string name) { this.Low = low; this.High = high; this.name = name; for (int i = low; i <= high; i++) BookTypeLookup.lookup.Add(i, this); } public override string ToString() { return name; } public static implicit operator BookType(int value) { BookType result = null; if (BookTypeLookup.lookup.TryGetValue(value, out result)) return result; throw new ArgumentOutOfRangeException("BookType not found"); } } 

它比普通的枚举更冗长,但它确实允许你以类似枚举的方式定义远程成员。

例如

  var bookType = (BookType)5; Console.WriteLine(bookType); 

不,这不对。 如果您尝试映射的数字常量确实具有相同的含义,则每个数字常量仍需要一个单独的成员。 像TextBook4,TextBook5等

你可以选择一本字典。

 var BookType = new Dictionary(); BookType.Add(1, "Novel"); BookType.Add(2, "Journal"); BookType.Add(3, "Reference"); BookType.Add(4, "TextBook"); BookType.Add(5, "TextBook"); BookType.Add(6, "TextBook"); BookType.Add(7, "TextBook"); BookType.Add(8, "TextBook"); BookType.Add(9, "TextBook"); BookType.Add(10, "TextBook"); int iBook = 5 Debug.Print "Book " + iBook + " is a " BookType[iBook] 

编辑 :如果它在类级别,您也可以只读声明字典。

您可以使用枚举作为字典值而不是字符串。

如果您可以自己将值分配给枚举字符串,那么您可以使用一些bitmagic将多个int值映射到相同的枚举值。 子类型可以是每个BookType (NovelTypes,JournalTypes等)的枚举。

在不利方面

  • 在转换为BookType时,它确实需要一些值修改
  • 每个子类型范围都是相同的大小(当前示例中为16)。
  • 它比简单的Novel = 3种映射Novel = 3可读性。

示例代码:

 class Program { ///  Number of subtypes reserved for each BookType.  private const byte BookTypeStep = 16; ///  Bitmask to use to extract BookType from a byte.  private const byte BookTypeExtractor = Byte.MaxValue - BookTypeStep + 1; ///  Bitmask to use to extract Book subtype from a byte.  private const byte BookSubTypeExtractor = BookTypeStep -1; public enum BookType : byte { Unknown = 0, Novel = BookTypeStep * 1, Journal = BookTypeStep * 2, Reference = BookTypeStep * 3, TextBook = BookTypeStep * 4, } static void Main(string[] args) { for(int i = 16; i < 80; i++) { Console.WriteLine("{0}\tof type {1} ({2}),\tsubtype nr {3}", i, i & BookTypeExtractor, (BookType)(i & BookTypeExtractor), i & BookSubTypeExtractor ); } Console.ReadLine(); } } 

这个例子的小说范围是16-31,期刊的范围是32-47等。

也许你想问一个相关的问题,那就是:你能不能有一个枚举(不确定我的术语是否正确,但我的例子会显示我的意思)对于每个值?

在C#中,您可以执行以下操作:

 public enum BookType { Novel = 1, Journal = 2, Magazine = 2, Reference = 3, TextBook = 4, LabWorkbook = 4, Dictionary = 5, Encyclopedia = 5 } 

这样,您可以在代码中使用BookType.JournalBookType.Magazine ,其中任何一个都与值2同义。 是否应该这样做是另一回事 – 我不熟悉支持或反对的论据(我想说“如果C#允许它,它一定是好的”,但那将是完全疯狂的)。

对你的问题最简单的答案是否。实现你想要的最简单的方法是:

 public enum BookType { Novel = 1, Journal = 2, Reference = 3, TextBook = 4 } public void bookOutput(int book) { if(book < 4) Console.Writeline("Book "+book+" is a " + ((BookType)book).ToString()); else Console.Writeline("Book "+book+" is a " + BookType.TextBook.ToString()); } 

我们的想法是让枚举成为单独的值,并使用逻辑语句处理范围。