Struct v/s Class in C# - Please explain the behavi

2019-07-18 04:42发布

Could someone please explain the behavior of this

  class testCompile
    {
       /*
        *   Sample Code For Purpose of Illustration
        */
       struct person 
       {
           public int age;
           public string name;

       }

        static void Main(string[] args)
        {
            List<person> Listperson = new List<person>();
            person myperson = new person();

            for (int i = 1; i <= 2; i++)
            { 
                //Assignment
                myperson.age = 22+i;
                myperson.name = "Person - " + i.ToString();
                Listperson.Add(myperson);
            }
            int x = 0;
            while (x < Listperson.Count)
            {
                //Output values
                Console.WriteLine("{0} - {1}", Listperson[x].name, Listperson[x].age);
                x++;
            }
        }
    }

/*  
    Output:
    Person - 1 - 23
    Person - 2 - 24
*/

Why am I not getting the same output for a class as that of a struct?

class testCompile
    {
       /*
        *   Sample Code For Purpose of Illustration
        */
       class person 
       {
           public int age;
           public string name;

       }

        static void Main(string[] args)
        {
            List<person> Listperson = new List<person>();
            person myperson = new person();

            for (int i = 1; i <= 2; i++)
            { 
                //Assignment
                myperson.age = 22+i;
                myperson.name = "Person - " + i.ToString();
                Listperson.Add(myperson);
            }
            int x = 0;
            while (x < Listperson.Count)
            {
                //Output values
                Console.WriteLine("{0} - {1}", Listperson[x].name, Listperson[x].age);
                x++;
            }
        }
    }
/*  
    Output:
    Person - 2 - 24
    Person - 2 - 24 
*/

10条回答
Fickle 薄情
2楼-- · 2019-07-18 04:52

In the second instance, you're addding a reference type. In fact, you're adding the same item, twice, since your

  = new person()

is not in the loop. So it always points to the same object you initialized here:

 person myperson = new person();

Even after it's added to your list, the changes affect it.

In the first instance, you're adding a struct each time, which is a value type, so will be copied into the list. Changes you make after that no longer refer to the object in the list, so they have different values.

查看更多
仙女界的扛把子
3楼-- · 2019-07-18 04:55

When you add the struct to the collection, it makes a copy of it. It's a value type. You'll end up with two distinct objects in the collection, each with different values. This is probably the expected behavior.

When you add the class, the reference type, to the collection, a new object is not created. You're actually adding two different references to the same object. You'll end up with (apparently) two objects with the same value. It's actually the same object, seemingly appearing twice in the collection.

查看更多
老娘就宠你
4楼-- · 2019-07-18 05:00

Structures are value types and classes are reference types. So in your first example when you add myperson to the list your adding a copy of myperson and the myperson variable still refers to a separate copy. In you second example myperson is a reference type so your adding two pointers to the same object.

查看更多
Animai°情兽
5楼-- · 2019-07-18 05:02

If you want same result then bring person declaration inside of the for loop:-

           // person myperson = new person();
           //Move the upper line inside the for loop
            for (int i = 1; i <= 2; i++)
            { 
               person myperson = new person();
                //Assignment
                myperson.age = 22+i;
                myperson.name = "Person - " + i.ToString();
                Listperson.Add(myperson);
            }

In struct you adding a value type hence separate values are stored, whereas in class you are adding reference to the object hence gettng same value.

查看更多
Luminary・发光体
6楼-- · 2019-07-18 05:05

You should understand key distinctions between structs (Value Types) and classes (Reference Type). You could easily find this information in Google or at SO.

When you add struct instance to List you create another separate copy for this instance, and when you change one element you did not change another.

But in case of classes you create one instance and uses this one "shared" instance with two references (list[0] and list1) and you could change this one instance through two different references, that's why when you change list[0] item it seems that you change list1 item too.

Consider following code:

var s1 = new SampleStruct { X = 1, Y = 1 };
var s2 = s1; 
//Creating separate copy
//Lets check this
Console.WriteLine(object.ReferenceEquals(s1, s2)); //Prints False

var c1 = new SampleClass { X = 1, Y = 2 };
var c2 = c1;
//We do not create any copy
// two references c1 and c2 "pointed" to one shared object
Console.WriteLine(object.ReferenceEquals(c1, c2)); //Prints True

Similar behavior we have when we pass parameter to function (or adding element to list).

查看更多
Rolldiameter
7楼-- · 2019-07-18 05:05

Classes are reference types, structs are value types.

When a value type is passed to a method as a parameter, a copy of it will be passed through. That means that you add two completely separate copies of the Person struct, one for each pass in the loop.

When a reference type is passed to a method as a parameter, the reference will be passed through. That mean that you add two copies of the reference to the same memory location (to the same Person object) - when making changes to this one object, you see it reflected in both references since they both reference the same object.

查看更多
登录 后发表回答