选择类还是结构体

One of the basic design decisions every framework designer faces is whether to design a type as a class (a reference type) or as a struct (a value type). Good understanding of the differences in the behavior of reference types and value types is crucial in making this choice.

每一个框架设计师都会面临的基本设计决策之一, 就是要将一个类型设计为类(引用类型)还是设计为结构(值类型). 熟悉了解引用类型和值类型的差异, 在这个选择上至关重要.

The first difference between reference types and value types we will consider is that reference types are allocated on the heap and garbage-collected, whereas value types are allocated either on the stack or inline in containing types and deallocated when the stack unwinds or when their containing type gets deallocated. Therefore, allocations and deallocations of value types are in general cheaper than allocations and deallocations of reference types.

引用类型和值类型之间的第一个区别是, 引用类型是在堆上分配, 由垃圾回收机制来回收, 而值类型是在堆栈上或在包含类型的内联中进行分配的, 在堆栈或包含其的类型释放时进行释放. 因此, 值类型的分配和释放一般比引用类型的分配和释放代价更低.

Next, arrays of reference types are allocated out-of-line, meaning the array elements are just references to instances of the reference type residing on the heap. Value type arrays are allocated inline, meaning that the array elements are the actual instances of the value type. Therefore, allocations and deallocations of value type arrays are much cheaper than allocations and deallocations of reference type arrays. In addition, in a majority of cases value type arrays exhibit much better locality of reference.

接下来, 引用类型的数组为超线分配, 这意味着数组元素只是对驻留在堆上的引用类型的实例的引用. 值类型数组是内联分配的, 这意味着数组元素就是值类型实例本身. 因此, 值类型数组的分配和释放比引用类型数组的分配和释放的代价少得多. 此外, 在大多数情况下, 值类型数组表现出更好的局部访问性(locality of reference).

The next difference is related to memory usage. Value types get boxed when cast to a reference type or one of the interfaces they implement. They get unboxed when cast back to the value type. Because boxes are objects that are allocated on the heap and are garbage-collected, too much boxing and unboxing can have a negative impact on the heap, the garbage collector, and ultimately the performance of the application. In contrast, no such boxing occurs as reference types are cast.

下一个差异与内存使用情况有关. 当值类型被转换为引用类型或实现引用类型的某一个接口时, 值类型将被装箱. 当它们被转换回值类型时, 它们将被拆箱. 因为箱子是在堆上分配并被垃圾回收的对象, 所以过多的装箱和拆箱可能会对堆、垃圾回收器以及最终应用程序的性能产生负面影响. 相比之下, 在转换引用类型时不会发生此类装箱拆箱操作.

Next, reference type assignments copy the reference, whereas value type assignments copy the entire value. Therefore, assignments of large reference types are cheaper than assignments of large value types.

接下来, 引用类型的分配是复制引用, 而值类型的分配将复制整个值. 因此, 大型引用类型的分配比大型值类型的分配代价更低.

Finally, reference types are passed by reference, whereas value types are passed by value. Changes to an instance of a reference type affect all references pointing to the instance. Value type instances are copied when they are passed by value. When an instance of a value type is changed, it of course does not affect any of its copies. Because the copies are not created explicitly by the user but are implicitly created when arguments are passed or return values are returned, value types that can be changed can be confusing to many users. Therefore, value types should be immutable.

最后, 引用类型通过引用传递, 而值类型通过值传递. 对引用类型的实例所做的更改会影响指向该实例的所有引用. 值类型实例在通过值传递时被复制. 当值类型的实例发生更改时, 它当然不会影响其任何副本. 因为副本不是由用户显式创建的, 而是在传递参数或返回值时隐式创建的, 所以许多用户对值类型可以被改变感到困惑. 因此, 值类型应该是不可改变的.

As a rule of thumb, the majority of types in a framework should be classes.There are, however, some situations in which the characteristics of a value type make it more appropriate to use structs.

作为一个经验法则, 框架中的大多数类型应该是类. 但是, 有些情况下, 值类型的特性使它更适合使用结构.

✓ CONSIDER defining a struct instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.

当类型很小并且通常生命周期短, 或者通常内嵌在其它对象内中, 将类型定义为结构体

X AVOID defining a struct unless the type has all of the following characteristics:

  • It logically represents a single value, similar to primitive types (int, double, etc.).
  • It has an instance size under 16 bytes.
  • It is immutable.
  • It will not have to be boxed frequently.

In all other cases, you should define your types as classes.

当一个类型有以下特性时, 可以定义为结构体

  • 逻辑上只是一个简单的值, 类似于基元类型
  • 它的实例大小小于16字节
  • 它不可改变
  • 它不会被频繁地装箱

MSDN地址: Choosing Between Class and Struct

补充:

  • 堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些
  • 结构表示如点、矩形和颜色这样的轻量对象,例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。在此情况下,结构的成本较低。
  • 在表现抽象和多级别的对象层次时,类是最好的选择
  • 大多数情况下该类型只是一些数据时,结构时最佳的选择

猜你喜欢

转载自blog.csdn.net/jingangxin666/article/details/81266913
今日推荐