新建一个.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.
参考文献: