为什么我应该使用Enum Int32的底层类型而不是字节?

时间:2012-04-18 19:50:34

标签: c# .net enums

鉴于以下枚举:

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

当我运行Microsoft代码分析工具时,它会告诉我:

  

CA1028:Microsoft.Design:如果可能,请创建基础类型“Enums.Operations_PerHourType”System.Int32而不是“byte”。

它永远不会超过几个可能的值,所以我将其声明为一个字节。他们为什么建议使用int32?未来可扩展性的更多价值?或者是否有性能提升?

3 个答案:

答案 0 :(得分:40)

查看MSDN的原因。

以下是摘录:

  

枚举是一种值类型,用于定义一组相关的命名   常量。默认情况下,System.Int32数据类型用于存储   恒定价值。即使您可以更改此基础类型,也是如此   大多数情况下都没有必要或推荐。注意没有   通过使用的数据类型实现了显着的性能提升   小于Int32。如果您不能使用默认数据类型,那么   应该使用一个与公共语言系统(CLS)兼容的积分   types,Byte,Int16,Int32或Int64以确保所有值   枚举可以在符合CLS的编程中表示   语言。

答案 1 :(得分:24)

在某些特定情况下,缩小基础类型会带来一些优势,例如与非托管代码接口时性能相关或强制特定内存布局。

考虑这个样本:

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

此代码占用大约40 KB的堆。现在将基础类型指定(取消注释)为byte并重新编译。哇。突然间我们只需要大约10 KB。

这样压缩内存有时会使程序变慢,而不是更快,具体取决于特定的访问模式和数据大小。除了进行一些测量并尝试推广到其他可能的情况之外,没有办法确定。较小数据的顺序遍历通常更快。

但是,养成一种习惯,只是因为它通常是可能的,有时是至关重要的,所以指定窄类型并不是一个好主意。由于周围更广泛的数据类型的内存对齐,内存节省很少实现。由于屏蔽填充字节所需的附加指令,性能要么相同要么稍差。

正如另一个答案已经说得好,请按照运行时优化的Int32人群进行操作,直到你必须开始分析和解决应用程序中的实际内存耗尽。

答案 2 :(得分:21)

根据文档,使用字节而不是INT32没有性能提升。除非有理由这样做,否则他们建议不要更改它。根本的想法是,.NET在许多情况下都针对使用INT32进行了优化,并且出于某种原因他们选择了枚举。你没有在你的场景中通过改变它获得任何东西,所以为什么要这么麻烦。

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

这也讨论了如何优化.NET以使用32位整数:.NET Optimized Int32