c# español - ¿Por qué debería hacer el tipo subyacente de un Enum Int32 en lugar de un byte?




string c++ (4)

Teniendo en cuenta la siguiente enumeración:

public enum Operations_PerHourType : byte
{
    Holes = 1,
    Pieces = 2,
    Sheets = 3,
    Strips = 4,
    Studs = 5
}

Cuando ejecuto la herramienta de análisis de código de Microsoft, me dice:

CA1028: Microsoft.Design: si es posible, cree el tipo subyacente de 'Enums.Operations_PerHourType' System.Int32 en lugar de 'byte'.

Nunca tendrá más de un par de valores posibles, por lo que lo declaré como un byte. ¿Por qué recomendarían usar int32? ¿Más valores para la escalabilidad futura? ¿O hay una mejora de rendimiento?


Answers

Echa un vistazo a MSDN por la razón.

Aquí hay un extracto:

Una enumeración es un tipo de valor que define un conjunto de constantes con nombre relacionadas. De forma predeterminada, el tipo de datos System.Int32 se utiliza para almacenar el valor constante. Aunque puede cambiar este tipo subyacente, no es necesario ni recomendado para la mayoría de los escenarios. Tenga en cuenta que no se obtiene una ganancia de rendimiento significativa utilizando un tipo de datos que sea más pequeño que Int32. Si no puede usar el tipo de datos predeterminado, debe usar uno de los tipos integrales compatibles con Common Language System (CLS), Byte, Int16, Int32 o Int64 para asegurarse de que todos los valores de la enumeración puedan representarse en conformidad con CLS lenguajes de programación.


Existen situaciones específicas en las que la reducción del tipo subyacente aporta algunas ventajas, por ejemplo, relacionadas con el rendimiento o que obligan a un diseño de memoria particular al conectarse a un código no administrado.

Considere esta muestra:

using System;

public enum Operations_PerHourType //   : byte
{
    Holes = 1,
    Pieces = 2,
    Sheets = 3,
    Strips = 4,
    Studs = 5
}

class Program
{
    static void Main()
    {
        long before = GC.GetTotalMemory(false);
        var enums = new Operations_PerHourType[10000];
        long after = GC.GetTotalMemory(false);

        Console.WriteLine(after - before);
        // output  (byte): 12218 (I'm using Mono 2.8)
        // output (Int32): 40960
    }
}

Este código consume aproximadamente 40 KB del montón. Ahora especifique (descomente) el tipo subyacente como byte y recompile. Guau. De repente solo necesitamos unos 10 KB.

La memoria de compactación como esta puede hacer que un programa sea más lento, no más rápido, dependiendo de los patrones de acceso particulares y los tamaños de datos. No hay forma de saber con seguridad que hacer algunas mediciones e intentar generalizar otras posibles circunstancias. El recorrido secuencial de datos más pequeños suele ser más rápido.

Sin embargo, no es una buena idea desarrollar el hábito de especificar tipos estrechos solo porque generalmente es posible y, a veces, crucial. Los ahorros de memoria rara vez se materializan debido a la alineación de la memoria de los tipos de datos más amplios circundantes. El rendimiento es entonces el mismo o un poco peor debido a las instrucciones adicionales necesarias para enmascarar los bytes de relleno.

Como otra respuesta ya lo ha expresado bien, siga la multitud de Int32 que está optimizado el tiempo de ejecución, hasta que tenga que comenzar a perfilar y abordar los problemas de memoria reales en su aplicación.


Según la documentación, no hay ganancia de rendimiento al usar un byte en lugar de INT32. A menos que haya una razón para hacerlo, recomiendan no cambiarlo. La idea subyacente es que .NET está optimizado para usar INT32 en muchos escenarios, y lo seleccionaron para enums por una razón. No se obtiene nada en su escenario al cambiarlo, así que, ¿por qué molestarse?

http://msdn.microsoft.com/en-us/library/ms182147.aspx

Esto también habla de cómo .NET está optimizado para usar enteros de 32 bits: .NET Optimized Int32


object Enum.Parse(System.Type enumType, string value, bool ignoreCase);

Así que si tuvieras un estado de ánimo llamado enum se vería así:

   enum Mood
   {
      Angry,
      Happy,
      Sad
   } 

   // ...
   Mood m = (Mood) Enum.Parse(typeof(Mood), "Happy", true);
   Console.WriteLine("My mood is: {0}", m.ToString());




c# .net enums