【问题标题】:What's the use of value types in .Net?.Net 中值类型的用途是什么?
【发布时间】:2010-09-07 11:10:56
【问题描述】:

official guidelines 表明这些方法的实际用途很少。有没有人有他们充分利用它们的例子?

【问题讨论】:

    标签: .net


    【解决方案1】:

    你应该在任何时候使用值类型:

    • 不需要使用类(不需要继承)
    • 您要确保不需要初始化类型。
    • 您有理由希望在堆栈空间中分配类型
    • 您希望类型是分配时完全独立的实体,而不是引用类型中的“链接”到实例。

    【讨论】:

    • 我可能会补充:当您不需要实体的身份时。比如二维点等等。
    【解决方案2】:

    在大多数情况下,最好模拟框架的行为。许多基本数据类型(例如ints)都是值类型。如果您有具有相似属性的类型,请使用值类型。例如,在编写Complex 数据类型或BigInteger 时,值类型是逻辑解决方案。框架使用值类型的其他情况也是如此:DateTimePoint 等。

    如有疑问,请改用引用类型。

    【讨论】:

      【解决方案3】:

      实际上,在 .net 3.5 SP1 之前,如Vance Morrison's blog 中所述,大量使用值类型存在性能问题。

      据我所知,绝大多数时候您应该使用类,而 JITter 应该保证良好的性能水平。

      结构具有“值类型语义”,因此将通过值而不是通过引用传递。我们可以在以下示例中看到这种行为差异:-

      using System;
      
      namespace StructClassTest {
      
        struct A {
          public string Foobar { get; set; }
        }
      
        class B {
          public string Foobar { get; set; }
        }
      
        class Program {
          static void Main() {
            A a = new A();
            a.Foobar = "hi";
            B b = new B();
            b.Foobar = "hi";
      
            StructTest(a);
            ClassTest(b);
      
            Console.WriteLine("a.Foobar={0}, b.Foobar={1}", a.Foobar, b.Foobar);
      
            Console.ReadKey(true);
          }
      
          static void StructTest(A a) {
            a.Foobar = "hello";
          }
      
          static void ClassTest(B b) {
            b.Foobar = "hello";
          }
        }
      }
      

      该结构将通过值传递,因此 StructTest() 将获得它自己的 A 结构,并且当它更改时 a.Foobar 将更改其新类型的 Foobar。 ClassTest() 将收到对 b 的引用,因此 b 的 .Foobar 属性将被更改。因此,我们将获得以下输出:-

      a.Foobar=hi, b.Foobar=hello
      

      因此,如果您需要值类型语义,那么这将是另一个将某些东西声明为结构的原因。有趣的是,.net 中的 DateTime 类型是一个值类型,因此 .net 架构师认为这样分配它是合适的,确定他们为什么这样做会很有趣:-)

      【讨论】:

        【解决方案4】:

        值类型,特别是结构和枚举,在面向对象编程中有适当的用途。

        正如 aku 所说,枚举是 .NET 中的一等公民,可用于各种事物,从颜色到对话框选项再到各种类型的标志。

        就我的经验而言,结构体非常适合作为数据传输对象;无逻辑的数据容器,尤其是当它们主要由原始类型组成时。

        当然,原始类型都是值类型,它们解析为 System.Object(不像 Java 中原始类型与结构无关并且需要某种包装器)。

        【讨论】:

          【解决方案5】:

          正是大多数其他人使用它们的目的......快速和轻量级的数据/值访问。并且非常适合将属性(当然是有意义的)分组到对象中。

          例如:

          • 显示/数据值差异,例如图像名称字符串对和控件路径(或其他)。您希望在后台工作的路径,但名称对用户可见。
          • 对象度量值的明显分组。我们都知道大小等,但在很多情况下,基本“指标”类型对您来说还不够。
          • 枚举值的“打字”,不仅仅是一个固定的枚举,但还不是一个成熟的类(已经提到过,只是想提倡)。

          记住differences between value and reference types 很重要。如果使用得当,它们可以真正提高代码效率,并使对象模型更加健壮。

          【讨论】:

            【解决方案6】:

            Au Contrare...您会发现 C/C++ 人涌向结构,也就是值类型。
            一个例子是数据包。如果您要传输/传输大量数据包,则可以使用值结构对数据包进行建模。
            原因:除了实例数据之外,将某些东西变成一个类会增加对象标头中的开销(我忘记了大约 8-16 字节)的开销。在不可接受的情况下,值类型是您最安全的选择
            另一种用途是您需要值类型语义 - 一旦您创建-初始化一个对象,它就是只读/不可变的,并且可以传递给 n 个客户端。

            【讨论】:

              【解决方案7】:

              我倾向于使用 enum 来避免幻数,我猜这可以通过 const 来克服,但 enum 允许您将它们分组。

              enum MyWeirdType {
              TypeA, TypeB, TypeC};
              
              switch(value){
              case MyWeirdType.TypeA:
              ...
              

              【讨论】:

                【解决方案8】:

                枚举是 .NET 世界的一等公民。至于结构,我发现在大多数情况下可以使用类,但是对于内存密集型场景,请考虑使用结构。作为一个实际示例,我使用结构作为 OSCAR (ICQ) 协议原语的数据结构。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-08-17
                  • 2015-05-09
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多