C#中,添加值类型和引用类型到List<T>集合有什么不同

新建一个.NET Core控制台项目,敲入下面代码,我们来测试将值类型和引用类型加入List<T>集合,有什么不同:

using System;
using System.Collections.Generic;

namespace NetCoreList
{
    //类People,是引用类型
    class People
    {
        public string Name
        {
            get;
            set;
        }
    }

    //结构体Person,是值类型
    struct Person
    {
        public string Name
        {
            get;
            set;
        }
    }


    class Program
    {
        //显示Person集合所有元素
        static void DisplayPersonCollection(List<Person> collection)
        {
            Console.WriteLine("==========PersonCollection==========");

            foreach (Person person in collection)
            {
                Console.WriteLine("Person:" + person.Name);
            }
        }

        //显示People集合所有元素
        static void DisplayPeopleCollection(List<People> collection)
        {
            Console.WriteLine("==========PeopleCollection==========");

            foreach (People people in collection)
            {
                Console.WriteLine("People:" + people?.Name);
            }
        }

        static void Main(string[] args)
        {
            //定义一个Person
            Person person = new Person()
            {
                Name = "Jack"
            };

            //定义一个People
            People people = new People()
            {
                Name = "Jack"
            };

            Console.WriteLine("person's name is:" + person.Name);
            Console.WriteLine("people's name is:" + people.Name);

            //定义Person集合personCollection
            List<Person> personCollection = new List<Person>();
            personCollection.Add(person);
            personCollection.Add(person);
            personCollection.Add(person);

            //定义People集合peopleCollection
            List<People> peopleCollection = new List<People>();
            peopleCollection.Add(people);
            peopleCollection.Add(people);
            peopleCollection.Add(people);

            People peopleNull = null;
            peopleCollection.Add(peopleNull);
            peopleCollection.Add(peopleNull);

            DisplayPersonCollection(personCollection);
            DisplayPeopleCollection(peopleCollection);

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();

            person.Name = "Tom";//更改person的Name
            people.Name = "Tom";//更改people的Name

            Console.WriteLine("person's name is:" + person.Name);
            Console.WriteLine("people's name is:" + people.Name);

            DisplayPersonCollection(personCollection);
            DisplayPeopleCollection(peopleCollection);

            Console.WriteLine("Press any key to end...");
            Console.ReadKey();
        }
    }
}

运行上面的代码,结果如下所示:

可以看到:

每次我们将值类型Person结构体的对象实例person,加入List<Person>集合personCollection时,相当于是复制了一个Person结构体对象实例,然后加入到List<Person>集合personCollection中,所以后面当我们修改对象实例person的Name属性为"Tom"后,personCollection集合中的三个Person结构体对象实例都没有改变,它们的Name属性还是"Jack"。

每次我们将引用类型People类的对象实例people,加入List<People>集合peopleCollection时,实际上是将同一个People类对象实例的引用(相当于指针),加入到了List<People>集合peopleCollection中,所以实际上List<People>集合peopleCollection中存储的都是People类对象实例的引用(相当于指针),前三个不为null的People类引用(相当于指针),指向的都是内存中同一个People类对象实例,所以后面当我们修改对象实例people的Name属性为"Tom"后,peopleCollection集合中三个不为null的People类对象实例都跟着改变了,因为它们三个实际上是同一个People类对象实例。

在微软的官方文档这个地方,有对List<T>集合类型的如下描述:

List<T> accepts null as a valid value for reference types and allows duplicate elements.

参考文献:

List<T> Class

List<T>.Add(T) Method

原文地址:https://www.cnblogs.com/OpenCoder/p/13368328.html