C # differences between reference types and value types

Source: Internet
Author: User

Parsing: CLR supports two types: Value Type and reference type. In the words of Jeffrey Richter (author of CLR via C #), "programmers who do not understand the differences between reference types and value types will introduce code into weird traps and many performance problems ". This requires us to correctly understand and use the value type and reference type.

Value types include the basic types of C # (declared with the keyword int, char, float, etc.), structure (type declared with the struct keyword), enumeration (type declared with the enum keyword ); the reference types include classes (types declared with the class keyword) and delegation (special classes declared with the delegate keyword ).

In C #, each type is either a value type or a reference type. Therefore, each object is either a value-type instance or a reference-type instance. Value-type instances are usually allocated on the thread stack (static allocation), but in some cases they can be stored in the heap. Objects of the reference type are always allocated (dynamically allocated) in the process heap ).

(1) in C #, whether a variable is a value or a reference only depends on its basic data type.

The basic data types of C # are not related to the platform. The pre-defined type of C # is not built into the language, but is built into the. NET Framework .. . NET uses the universal Type System (CTS) to define predefined data types that can be used in the intermediate language (IL. C # All data types are objects. They can have methods, attributes, and so on. For example, when C # declares an int variable, the Declaration is actually an instance of System. Int32 in CTS (general type System:

Int I;

I = 1;

String s;

S = I. ToString ();

Describes how each type of CTS is related.

 

(2) System. Object and System. ValueType.

Both the reference type and value type inherit from the System. Object Class. The difference is that almost all reference types are inherited directly from System. Object, while the value type inherits its subclass, that is, the System. ValueType type is inherited directly. As a base class of all types, System. Object provides a set of methods that can be found in all types. It includes the toString method and clone method. System. ValueType inherits System. Object. It does not add any Members, but overwrites some inherited methods to make them more suitable for value types.

(3) value type.

All value types of C # are implicitly derived from System. ValueType:

Struct: struct (directly derived from System. ValueType ).

Value Type: integer, sbyte (System. SByte alias), short (System. int16), int (System. int32), long (System. int64), byte (System. byte), ushort (System. UInt16), uint (System. UInt32), ulong (System. UInt64), char (System. char ).

Float: float (System. Single), double (System. Double ).

The high-precision decimal type used for financial computing: decimal (System. Decimal ).

Bool type: bool (alias of System. Boolean ).

User-defined struct (derived from System. ValueType ).

Enumeration: enum (derived from System. Enum ).

Can be empty.

Each value type has an implicit default constructor to initialize the default value of this type. For example:

Int I = 0;

It is equivalent:

Int I = new int ();

When the new operator is used, a default constructor of a specific type is called and a default value is assigned to the variable. In the preceding example, the default constructor assigns the value 0 to I.

All value types are seal, so a new value type cannot be derived.

It is worth noting that System. ValueType is directly derived from System. Object. That is, System. ValueType is a class type rather than a value type. The key is that ValueType overrides the Equals () method to compare the value type by instance value rather than by reference address. You can use the Type. IsValueType attribute to determine whether a Type is a value Type:

TestType testType = new TestType ();

If (testTypetype. GetType (). IsValueType)

{

Console. WriteLine ("{0} is value type.", testType. ToString ());

}

(4) Reference Type

C # has the following reference types:

Array (derived from System. Array)

You need to define the following types.

Class: class (derived from System. Object );

Interface: interface (the interface is not a "thing", so there is no problem where it is derived. The interface only represents a contract Convention [contract]).

Delegate: Delegate (derived from System. delegate ).

Object (alias of System. Object );

String: String (alias of System. string ).

We can see that:

If the reference type is the same as the value type, the struct can also implement interfaces. The reference type can derive a new type, but the value type cannot. The reference type can contain null values and the value type cannot; the value assignment of a reference type variable only copies the reference of an object instead of the object itself. When a value type variable is assigned to another value type variable, the included values are copied.

(5) memory allocation.

Value-type instances are often stored on stacks. But there are also special cases. If a class instance has a value type field, the field will be saved in the same place as the class instance, that is, the heap. However, reference objects are always stored in the heap. If a structure field is of the reference type, only the reference itself is stored with the structure instance (on the stack or stack, depending on the situation ). For example:

Public struct ValueTypeStruct

{

Private object referenceTypeObject;

Public void Method ()

{

ReferenceTypeObject = new object ();

Object referenceTypeLocalVariable = new object ();

}

}

ValueTypeStruct valueTypeStructInstance = new ValueTypeStruct ();

ValueTypeStructInstance. Method ();

// Where are referenceTypeObject and referenceTypeLocalVariable stored?

Look at valueTypeStructInstance. This is a struct instance. It seems that the whole block is on the stack. However, the referenceTypeObject field is of the reference type, and the local variable referenceTypeLocalVarible is also of the reference type.

Public class ReferenceTypeClass

{

Private int _ valueTypeField;

Public ReferenceTypeClass ()

{

_ ValueTypeField = 0;

}

Public void Method ()

{

Int valueTypeLocalVariable = 0;

}

}

ReferenceTypeClass referenceTypeClassInstance = new ReferenceTypeClass ();

// _ Where is valueTypeField stored?

ReferenceTypeClassInstance. Method ();

// Where can valueTypeLocalVariable be stored?

ReferenceTypeClassInstance has the same problem. The referenceTypeClassInstance itself is a reference type and should be deployed on the hosting stack as a whole. But the field _ valueTypeField is a value type, and the local variable valueTypeLocalVariable is also a value type. Are they on the stack or on the managed stack?

The correct analysis of the above situation is that the reference type stores a reference in the stack, and its actual storage location is in the managed heap. For convenience, the reference type is deployed on the managed stack. The value type is always assigned to the place it declares. When it is used as a field, the variable (Instance) to which it belongs is stored; when it is used as a local variable, it is stored on the stack.

(6) Identify the use cases of value types and reference types.

In C #, we use struct/class to declare a type as value type/reference type. Consider the following example:

SomeType [] oneTypes = new SomeType [1, 100];

If SomeType is a value type, you only need to allocate it once, and the size is 100 times that of SomeType. If SomeType is of the reference type, it needs to be allocated for 100 times at the beginning. After being allocated, each element value in the array is null, and then 100 elements are initialized. A total of 101 assignments are required for the result. This will consume more time and cause more memory fragments. Therefore, if the type is mainly responsible for data storage, the value type is suitable.

Generally, value types (not supporting polymorphism) are suitable for storing data that is operated by C # applications, and reference types (supporting polymorphism) should be used to define the behavior of applications. Generally, we create more reference types than value types. If the following conditions are met, we should create a value type:

This type is mainly used for data storage.

Common interfaces of this type are completely defined by the Access attributes of some data members.

This type can never be a subclass.

This type does not have polymorphism.

Answer: in C #, whether a variable is a value or a reference only depends on its data type.

The value types of C # include struct (numeric type, bool type, user-defined struct type), enumeration, and null type.

C # references include arrays, user-defined classes, interfaces, delegates, objects, and strings. Array elements, whether of the reference type or value type, are stored on the managed stack.

The reference type stores a reference in the stack, and its actual storage location is located in the managed heap. The reference type is deployed on the hosting platform. The value type is always assigned to the place it declares: when it is used as a field, it is stored with the variable (Instance) to which it belongs; when it is used as a local variable, it is stored on the stack. Value types have better efficiency in memory management and do not support polymorphism. They are suitable for storing data. The reference types support polymorphism and are suitable for defining the behavior of applications.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.