C # Value types and reference types

Source: Internet
Author: User

Objective

In general, value types are stored on stacks, reference types exist in heaps, value types are converted to reference types called box, reference types are converted to value types in unbox, recently read a book Discover value types and reference types much more than that.

I find that at a few points my understanding has been wrong:

Error 1. A struct is a value type, and it has no relation to System.Object.

The direct base class of a struct is System.ValueType, and its base class is Sysem.object, and the basic types of int, bool, and so on are all structs. So all C # types inherit from System.Object.

Error 2. Value type conversion to interface type is not boxed

We all know that object obj = 3 will be boxed; In fact iequatable<int> obj = 3; It will be boxed as well as the previous one.

Error 3. equals of a struct type is not boxed.

Not only boxed, but also two times!

Error 4: Packing, unpacking the memory distribution.

After boxing, the heap is redistributed, in addition to related values, function table pointers, memory alignment and so on, and one missing is a reference to this boxed object.

Body

namespaceconsoleapplication1{//System.ValueType-System.Object    structpoint2d { Public intXGet;Set; }  Public intYGet;Set; } //version 1         Public Override BOOLEquals (Objectobj) {            if(! (obj isPOINT2D))return false; POINT2D Other=(point2d) obj; returnX = = Other. X && Y = =Other .        Y }        //Version 2         Public BOOLEquals (point2d other) {returnX = = Other. X && Y = =Other .        Y }        //Version 3         Public Static BOOL operator==(point2d A, point2d b) {returnA.equals (b); }         Public Static BOOL operator!=(point2d A, point2d b) {return! (A = =b); }    }    structPoint2d_v4:iequatable<point2d_v4>    {         Public intXGet;Set; }  Public intYGet;Set; } //version 1         Public Override BOOLEquals (Objectobj) {            if(! (obj isPOINT2D_V4))return false; Point2d_v4 Other=(point2d_v4) obj; returnX = = Other. X && Y = =Other .        Y }        //Version 2         Public BOOLEquals (Point2d_v4 other) {returnX = = Other. X && Y = =Other .        Y }        //Version 3         Public Static BOOL operator==(Point2d_v4 A, point2d_v4 b) {returnA.equals (b); }         Public Static BOOL operator!=(Point2d_v4 A, point2d_v4 b) {return! (A = =b); }    }     Public classEmployee { Public stringName {Get;Set; } //The hashcode is base on the IT cotent         Public Override intGetHashCode () {returnName.gethashcode (); }    }    classProgram {Static voidMain (string[] args) {            //version 1POINT2D A =NewPOINT2D (), B =Newpoint2d (); //Object test = b;//box B from Value type to reference type//A.equals (b);//box A to invoke the virtual function Equals//If we have 10,000,000 points, we'll do 20,000,000 box operation, on 32-bit system, one box'll allocate Bytes. //Version 2//How to avoid boxing override the equals. //A.equals (b);//no need box A or B this time. //Version 3//bool IsEqual = a = = B;//no boxing here. //It seems OK now, but there are a edge case would cause boxing at CLR generic. We need implement Iequatable //point2d_v4 i = new Point2d_v4 (), j = new Point2d_v4 (); //iequatable<point2d_v4> k = i;//box occurs here, the value type to interface requires boxing. //I.equals (j);//No box occurs//once boxing, they is not having relationship to orignal type. The best practice was let the value type immutable, l             Ike System.DateTime. //point2d_v4 point = new Point2d_v4 {X = 5, Y = 7}; //point2d_v4 anotherpoint = new Point2d_v4 {X = 6, Y = 7}; //iequatable<point2d_v4> equatable = point;//boxing occurs here//equatable. Equals (Anotherpoint); //returns false//Point .            X = 6; //Point . Equals (Anotherpoint); //returns True//equatable. Equals (Anotherpoint); //returns false, the box is not modified! //Then we need the hashcode, if you know about the HashKey in Datastructure. The hashcode are used for ID            Entity one or more than one items. //Here is some requirements to the Hashcode function://1. If the item is equal, the hashkey must be equal. //2. If the item is equal, the hashkey should not equal, and not must. //3. The GetHashCode function should fast. //4. The hashcode should not a change.Hashset<employee> employees =NewHashset<employee>(); Employee Kate=NewEmployee {Name ="Kate Jones" }; Employees.            ADD (Kate); Kate. Name="Kate Jones-smith"; //It really shock me, I don ' t notice this before.            BOOLhas = employees. Contains (Kate);//returns false!        }    }}

version 1:

public override bool Equals (object obj)

First the parameter ojbect will do a boxing, and then call equals because it is a virtual function, and the value type does not have a function pointer table, cannot call virtual function, must be converted to reference type, in order to invoke, I can actually see do box with ILDASM.

Version 2:
When we overload the Equals function, you avoid calling virtual functions, which avoids two boxing.

Version 3:
Make the comparison more complete, and reload the = =,! =.

Version 4:
Inherited from IEquatable, which is used in CLR generics. Further validation is required.

Version 5:
Some suggestions were made on the design of Hashcode. Do not rely on mutable things, or, as the above example demonstrates, potential instability.

Summarize
1. Use value types when we create a large number of instances, such as 10,000,000
2. Override Equals, Oeverload equals, implement iequatable<t>, overload = =,! =,
3. Override GetHashCode
4. Make the value type constant


Reference

<<pro. Net performance>>




C # Value types and reference types

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.