son posibles rangos con enumeraciones?

En C #, ¿puedes usar rangos de números en tipos de enumeración, por ejemplo?

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

EDITAR: la razón por la que se necesita esto es para convertir desde un número al tipo de enumeración, por ejemplo:

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

y la salida esperada es: El libro 5 es un libro de texto.

De acuerdo con el estándar de C # (p612, el lenguaje de progtwigción de C #), el valor dado a una enumeración debe ser un entero constante (o cualquier tipo similar: long, byte, sbyte, short, etc.), por lo que un rango de valores no es válido .

Mi comstackdor (VS2008) está de acuerdo con la especificación.

Ya que no puedes repetir nombres dentro de una enumeración, lo más cercano que obtendrás es algo como esto:

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

Que en realidad es bastante feo. Quizás una enumeración no sea la solución a su problema particular …

Como han dicho otros, no, no es posible. Es posible combinar valores de enumeración si son indicadores:

 [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 } 

Como no puede asignar un rango de valores a una enumeración, pensé en un enfoque alternativo para asignar una enumeración como valor límite (el ejemplo se basa en el tiempo):

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

Esto se supone que la enumeración está ordenada y funciona de forma inesperada con valores firmados (-).

Un poco fuera de lugar, puedes simular enums usando clases normales con campos de solo lectura.

Por ejemplo, algo similar a esto resolvería tu problema:

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

Es un poco más detallado que una enumeración normal, pero le permite definir miembros a distancia de una manera similar a la enumeración.

p.ej

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

No, no es. Si las constantes numéricas que intentas asignar tienen el mismo significado, aún necesitarías un miembro separado para cada constante numérica. Como TextBook4, TextBook5, etc.

Puedes optar por un diccionario más bien.

 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] 

Editar : También puede declarar su diccionario de solo lectura si está en el nivel de clase.

Puede utilizar una enumeración como valor de Diccionario en lugar de cadena.

Si puede asignar los valores a enum-strings, puede usar bitmagic para asignar múltiples valores int al mismo valor enum. Los subtipos pueden ser enumerados para cada BookType (NovelTypes, JournalTypes, etc.).

A la baja

  • requiere una modificación de valor cuando se BookType a BookType
  • cada rango de subtipo es del mismo tamaño (16 en el ejemplo actual).
  • es un poco menos legible que el tipo de mapeo Novel = 3 simple.

Código de ejemplo:

 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(); } } 

Este ejemplo tiene rangos de 16-31 para Novelas, 32-47 para revistas, etc.

Tal vez quisiste hacer una pregunta relacionada, que es: ¿puedes tener más de una enumeración (no estoy seguro de que tenga la terminología correcta, pero mi ejemplo mostrará lo que quiero decir) para cada valor?

En C #, puedes hacer algo como esto:

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

De esta manera, puede usar BookType.Journal o BookType.Magazine en su código, cualquiera de los cuales es sinónimo del valor 2 . Si se debe hacer esto es otro asunto: no estoy familiarizado con los argumentos a favor o en contra (me gustaría decir “si C # lo permite, debe estar bien”, pero eso sería una locura).

La respuesta más sencilla a su pregunta es No. La forma más fácil de lograr lo que desea es:

 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()); } 

La idea es dejar enumerar los valores individuales y manejar el rango con declaraciones lógicas.