. NET Framework-code instances that reference traps are shared

Source: Internet
Author: User
1 values equal, objects are equal by default?
What are the default rules that determine the existence of a reference type in a. NET container? Determines whether the pointer values are equal.

        private static list<int> List;                static void Main (string[] args)        {                    //new instance Instance1            MyObject Instance1 = new MyObject ();            Instance1. Value = ten;                        New list            list<myobject> list = new list<myobject> ();                        Reference instance Instance1            list. ADD (Instance1);                        New instance: Instance2            MyObject instance2 = new MyObject ();                        The assignment is Instance1. Value            Instance2. Value = Instance1. Value;               }    }

The Model class used:

            public class MyObject            {public                int Value {get; set;}            }

Here are 1 tests:

            Even if value is equal, the memory address of Instance2 and Instance1 is not equal!            bool IsExistence1 = list. Contains (INSTANCE2);            Isexistence1:false;

This test result is falsebecause they point to different memory addresses, even though the values are equal, which is the case of "equal values and unequal objects" .
  
Reference type if you want to determine whether the value is equal based on one of the property values, then you need to implement the IEquatable interface!
If you want to continue to see if the object is equal based on the value equality, refer to the article: C # container, interface class, performance

2 Reference traps?

  One object refers to another object, one changes, and the other changes . For example, merging two dictionaries, the merge result is right, but it accidentally changes the original object.

Give an example here:

            var dict1 = new dictionary<string, list<string>> (); Dict1. ADD ("Qaz", new list<string> () {"100"});//contains Qaz key Dict1.            ADD ("Wsx", new list<string> () {"13"});            var dict2 = new dictionary<string, list<string>> (); Dict2. ADD ("Qaz", new list<string> () {"11"}), and//also contains Qaz key dict2.            ADD ("EDC", New List<string> () {"17"});            Merge 2 dictionaries to dict var dictcombine = new dictionary<string, list<string>> (); foreach (Var ele in Dict1)//Get Dict1 {dictcombine. ADD (ele. Key,ele.             Value); } foreach (Var ele in dict2)//Get Dict2 {if (Dictcombine.containskey (ele. Key)//Check repeat Dictcombine [Ele. Key]. AddRange (ele.                 Value); else {dictcombine. ADD (ele. Key,ele.                 Value); }            }

Dictcombine results are correct, {"Qaz", "100" and "one"}, {"Wsx", "},{", "EDC", "17"}
But what about the results of Dict1? It's been changed! Dict1 unexpectedly changed {"Qaz", "100" and "one"}, {"Wsx", "13"}. correct merger, should not change dict1!

Analysis Reason

Dictcombine first added the key value of Dict1, that is, the key value of Dictcombine refers to the Dict1 key value; Next, when merging Dict2, first determine whether Dictcombine contains the Dict2 key, if included, It is added to the key value of the Dictcombine, and the value refers to the same object, which is the value added in the Dict1 key. Dictcombine[ele. Key] and Dict1[ele. Key] Reference is equal to the validation:

BOOL Flag = object. ReferenceEquals (Dictcombine[ele. Key], Dict1[ele. Key]);//true

Positive solution

Avoid Dictcombine[ele. Key] and Dict1[ele. Key] Reference equality!!!

dictionary<string, list<string>> dict = new dictionary<string, list<string>> ();            The keys are all merged into Dictcombine, and the values are the newly created            foreach (var key in Dict1. Keys)            {                if (!dictcombine.containskey (key))                    Dictcombine.add (Key, New list<string> ());            }            foreach (Var key in Dict2. Keys)            {                if (!dictcombine.containskey (key))                    Dictcombine.add (Key, New list<string> ());            }     Add values to the            foreach (Var ele in Dict1)            {dictcombine[ele, respectively                . Key]. AddRange (ele. Value);            }            foreach (Var ele in dict2)            {                Dictcombine[ele. Key]. AddRange (ele. Value);            }

The dictcombine merge result is correct, and the DICT1,DICT2 has not changed!

Summary
   The use of reference equivalence brings a number of benefits, such as the reference value between functions (by reference). However, if the use of improper, it will bring us some unnecessary trouble.

3 references improperly damaged encapsulation?
  
It is particularly easy to overlook the encapsulation of a private field in an encapsulated class as the return value of an interface method, which destroys the encapsulation of the class. If this problem is ignored, there may be some puzzling problems.
  
As shown in the following code,
  

public class testprivateencapsulate{    private list<object> _refobjs;    Public list<object> Getrefobjs ()    {        _refobjs = new list<object> ();        ...        ...       Other logical processing calculated by _refobjs={1,4,2};            return _REFOBJS; Return private field    } public    Object Getsumbyiterrefobjs ()    {        if (_REFOBJS = = null)            return null;        foreach (var item in _refobjs)        {            ...//processing logic        }  }}

Now using the class testprivateencapsulate we just wrote, we'll start by creating an instance,

Testprivateencapsulate test = new Testprivateencapsulate ();

Then call:

list<object> WANTEDOBJS = Test. Getrefobjs ();

The expected WANTEDOBJS returned should have 3 elements of the shaping type, 1,4,2.

Go on:

list<object> sol = wantedobjs; We point Sol to Wantedobjssol.add (5); add element 5

When we want to go back and calculate, the original WANTEDOBJS element sums:

Test. Getsum ();

We accidentally got 12, not the expected 7. What is this for?

After careful analysis, we found that we called in the client, Sol. ADD (5) indirectly modifies the testprivateencapsulate inside variable: _REFOBJS, which is modified by {1,4,2} for {1,4,2,5}.

  The private variable was modified on the client! This is the side effect of the interface returning private variables!

  Positive solution:

    Change the original public to private    list<object> Getrefobjs ()    {        _refobjs = new list<object> ();        ...        ...       Other logical processing calculated by _refobjs={1,4,2};            return _REFOBJS; Return private field    }    //Only with read-only properties public    refobjs    {        get         {            getrefobjs ();                        return _refobjs;         }    }

Set a public field with only read-only properties, getrefobjs the original public method to private method Getrefobjs, so that the client is not possible to modify the private field!

Summarize
object's property values are equal, but object references are not necessarily equivalent;
Two or more objects refer to an object, and if the object is modified, all the reference attribute values are also modified;
The member returns the encapsulated reference variable, which destroys the encapsulation.

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.