Si tengo la siguiente enumeración:

public enum ReturnValue{
    Success = 0,
    FailReason1 = 1,
    FailReason2 = 2
    //Etc...
}

Puedo evitar la proyección de cuando yo regrese, como este:

public static int main(string[] args){
    return (int)ReturnValue.Success;
}

Si no, ¿por qué no un valor de enumeración tratado como un int por defecto?

8 Comentarios

  1. 49

    las enumeraciones se supone que el tipo de seguro. Creo que ellos no hacen implícitamente lanzarse a desalentar a otros usos. Aunque el framework permite asignar un valor constante para ellos, usted debe reconsiderar su intención. Si sobre todo el uso de la enumeración para almacenar valores constantes, considere el uso de una clase estática:

    public static class ReturnValue
    {
        public const int Success = 0;
        public const int FailReason1 = 1;
        public const int FailReason2 = 2;
        //Etc...
    }

    Que le permite hacer esto.

    public static int main(string[] args){
        return ReturnValue.Success;
    }

    EDITAR

    Cuando hacer desea proporcionar a los valores de una enumeración es cuando se desea combinar. Vea el ejemplo de abajo:

    [Flags] //indicates bitwise operations occur on this enum
    public enum DaysOfWeek : byte //byte type to limit size
    {
        Sunday = 1,
        Monday = 2,
        Tuesday = 4,
        Wednesday = 8,
        Thursday = 16,
        Friday = 32,
        Saturday = 64,
        Weekend = Sunday | Saturday,
        Weekdays = Monday | Tuesday | Wednesday | Thursday | Friday
    }

    Esta enumeración puede ser consumido por el uso de bit a bit de matemáticas. Vea el ejemplo de abajo para algunas aplicaciones.

    public static class DaysOfWeekEvaluator
    {
        public static bool IsWeekends(DaysOfWeek days)
        {
            return (days & DaysOfWeek.Weekend) == DaysOfWeek.Weekend;
        }
    
        public static bool IsAllWeekdays(DaysOfWeek days)
        {
            return (days & DaysOfWeek.Weekdays) == DaysOfWeek.Weekdays;
        }
    
        public static bool HasWeekdays(DaysOfWeek days)
        {
            return ((int) (days & DaysOfWeek.Weekdays)) > 0;
        }
    
        public static bool HasWeekendDays(DaysOfWeek days)
        {
            return ((int) (days & DaysOfWeek.Weekend)) > 0;
        }
    }
    • Funciona como un encanto, Gracias! Extraño que puede definir una enumeración: «public enum MyEnum : int{ … }» y no tiene sus valores implícitamente hormigón. No hay ningún concepto de un «genérico enum» es la que hay? – public enum<int> MyEnum o es completamente ridículo?
    • Usted puede delcare tipo enum «public enum ReturnValue : int», que exige que los valores son de tipo int. Todavía no proporcionar la conversión implícita. La edición para mostrar cuando es es una buena idea utilizar los valores de una enumeración.
    • Una pequeña sugerencia de uso static readonly int en lugar de const, en el caso de valores de los cambios en futuras versiones. Usted no quiere que las personas que llaman tienen ese valor compilado en su código.
    • Miré hacia arriba a esta pregunta porque quiero llamar BackgroundWorker.ReportProgress(int) sin encasillamiento…estoy harto de la prepotencia de algunos miembros de la C# de la comunidad que «no hay ningún caso de uso»…es como que no he programado mucho
  2. 3

    No hay conversión implícita debido a que la enumeración no tiene que usar int como el tipo subyacente. Si su enumeración se utiliza un valor de este tipo como el tipo subyacente, por ejemplo, no hay ninguna conversión implícita de uint int.

    • Dos upvotes? Me parece que esta respuesta inútil en el que contesta a la pregunta que fue escrito, pero no, la pregunta obvia que se le había pedido. Lo que si se define enum MyEnum : int {}?; entonces no, pero que efectivamente hace uso de int como tipo subyacente; y todavía no existe una conversión implícita. sadpanda 🙁
  3. 3

    El c# enum es inútil.

    Puede evitar la proyección de su tipo Y restringir los valores que se pueden convertir de forma explícita para su tipo por hacer una clase cerrada, y proporcionar implícito/explícito operadores de conversión.

    • Proporcionar implícito un operador de conversión de tipo genérico int para que usted no tiene que echar.
    • Proporcionar una explícita del operador para la conversión de int a su tipo, lo que genera un error si el número entero no cumple con la restricción, tales como (int x) => x >= 0 && x <= 2).

    Si el uso de esta técnica, crear un genérico inmutable de la clase base como ConstrainedNumber<T>, que tiene un constructor que acepta un valor de T y el delegado de la restricción: delegate bool NumberConstraint<T>(T value). El constructor debe ejecutar el valor a través de la restricción de delegado, y lanzar una excepción si no cumple la restricción. La clase base debe también cuidar de la conversión implícita de la operación a T, y debe ocuparse de la igualdad por la sobrecarga de objeto.Equals(object) y el objeto.GetHashCode(), definiendo == y != operadores para el tipo ConstrainedNumber<T>, y la aplicación de IEquatable<T> y IEquatable<ConstrainedNumber<T>>. También se recomienda la definición de un constructor de copia de la clase base, y todos los tipos derivados. La clonación puede ser aplicado de forma limpia en la clase base por recuperar el constructor de copia a través de la reflexión, pero esto es totalmente opcional. Usted puede averiguar el ConstrainedNumber<T> aplicación a ti mismo, a menos que ya he publicado en stackoverflow en algún lugar.

    Puede proporcionar denomina estática de sólo lectura de los valores de la derivada ConstrainedNumber, de modo que usted puede tener acceso a ellos sólo como una enumeración.

    public sealed class ReturnValue: ConstrainedNumber<int>
    {
        public static readonly NumberConstraint<int> constraint = (int x) => (x >= 0 && x < 3);
    
        public static readonly ReturnValue Success = new ReturnValue(0);
        public static readonly ReturnValue FailReason1 = new ReturnValue(1);
        public static readonly ReturnValue FailReason2 = new ReturnValue(2);
    
        private ReturnValue( int value ): base( value, constraint ) {}
        private ReturnValue( ReturnValue original ): base (original) {} //may be used to support IClonable implementation in base class
        public static explicit operator ReturnValue( int value )
        {
            switch(value) //switching to return an existing instance is more efficient than creating a new one and re-checking the constraint when there is a limited number of allowed values; if the constraint was more generic, such as an even number, then you would instead return a new instance here, and make your constructors public.
            {
                case 0: return Success;
                case 1: return FailReason1;
                case 2: return FailReason2;
            }
            throw new ArgumentException( "Value fails to meet the constraint defined for " + typeof(ReturnValue).FullName + ".", "value" );
        }
    
    }

    Usted puede utilizar esta técnica para cualquier restricción. Por ejemplo, una clase denominada EvenNumber puede tener una restricción que devuelve true si el número es par. En ese caso, usted acaba de hacer su constructores público, y simplificar su conversión estática operador acabo de volver de un nuevo EvenNumber, en lugar de cambiar a devolver uno de los limita a las instancias existentes.

    Podría ser utilizado como esta:

    EvenNumber x = (EvenNumber)2;
    EvenNumber y = (EvenNumber)3; //throws exception "Value fails to meet the constraint defined for {namespace}.EvenNumber."  A c# enum would stupidly allow such a cast, creating an invalid EvenNumber, breaking the object-oriented model
    int z = x; //implicit conversion, no cast necessary;
  4. 2

    Las enumeraciones y enteros, simplemente, no son implícitamente lanzarse como por la especificación (excepto para el literal a 0, lo que es permitido para las pruebas de comparación /tareas /etc). La conversión explícita es todo lo que se necesita, sin embargo.

    • (spec 13.1.3 y 13.2.2 de ECMA 334v4)
    • Sería agradable si usted podría reemplazar el operador de igualdad para las enumeraciones
    • podría escribir un método de extensión, tal vez. No es lo mismo, pero…
  5. 0

    No, usted no puede evitar la fundición; de por qué no hay una conversión implícita, no sé, pero no hay.

  6. 0

    Por extraño que parezca, esto no es específico para el .NET Framework, pero sólo para C#. Como otros comentaristas ya han señalado, en C#, esto es, básicamente, una especificación de la lengua. El mismo no es cierto en VB.NET.

    Retirar el MSDN página de referencia para Las enumeraciones en VB.NET. Tenga en cuenta que usted puede especificar el tipo de datos de una enumeración en la declaración Enum tiempo.

    Que significa que, si usted realmente no desea jugar con su código con los modelos a (int), podría escribir su enumeración en VB.NET declarar como un entero, entonces el uso que la Enumeración de C#.

    Recordar cómo nos dijeron ordenadores de hacer nuestra vida mucho más simple? 🙂

    • Te quedarás en el mismo problema aquí, ya que está consumiendo el enum en C#, y recuerda, en C# no se puede convertir implícitamente la enumeración! Estás de nuevo al cuadrado uno 😉
  7. 0

    Puede atribuir este comportamiento a la intención básica detrás de la creación de las Enumeraciones… para crear un conjunto de constantes con nombre que sólo puede haber especificado (o defecto) de los valores según el tipo subyacente.

    Hay dos cuestiones a considerar, en relación a su pregunta:

    1. Un Enum valor no puede ser tratada como un int por defecto, porque entonces usted podría ser capaz de proporcionar cualquier entero y no habría tiempo de compilación de verificación para validar que el número entero no en el hecho de existir como un valor de la Enumeración.

    2. De fundición se hace necesaria puesto que usted está tratando de convertir el consejo de tipo (de tipo YourCustomEnum que se deriva de la System.Enum de clase) para el tipo subyacente, es decir, int o byte, etc.

  8. -2

    Cómo sobre el uso de los Miembros estáticos de una Clase?

    //enum DocInfos { DocName, DocNumber, DocVersion};
    public class DocInfos
    {
        public static int DocName = 0;
        public static int DocNumer = 1;
        public static int DocVersion = 2;
    }

                Doc = new string[DocInfos.DocVersion];
                //Treffer
                Doc[DocInfos.DocName] = TrimB(HTMLLines[lineCounter + 2])

    • Sólo para tu INFORMACIÓN-yo no voto esta abajo, pero apuesto a que fue rechazada b/c es redundante de la parte superior votado respuesta como incorrecta. La clase DocInfos debe ser estático.

Dejar respuesta

Please enter your comment!
Please enter your name here