Unity 基础 之 List 作为参数传递的值变化的三种情况注意

 

目录

Unity 基础 之 List 作为参数传递的值变化的三种情况注意

一、简单介绍

二、基本概念

三、三点注意

四、代码示例说明三点注意

1、测试代码

2、运行结果


 

一、简单介绍

Unity中的一些基础知识点。

本片介绍 List 在作为 参数传递的时候的一些之变化情况。

 

二、基本概念

所属命名空间:System.Collections.Generic

public class List : IList, ICollection, IEnumerable, IList, ICollection, IEnumerable

List类是 ArrayList 类的泛型等效类。该类使用大小可按需动态增加的数组实现 IList 泛型接口。

泛型的好处: 它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转换,所以性能得到提高。

 

三、三点注意

1)list类型是引用类型

2)引用本身是类似于一个“保存地址的值变量”
所以从方法外部传入引用到方法里,那么其实引用本身是复制了一份副本来给方法里使用的,只是说这个复制的引用副本和之前的引用的内容(也就是所指向的对象内存地址)是一样的,所以通过引用操作对象的数据时,可以看到2个引用都操作的同一个对象;但如果你是修改了引用副本本身的值内容(将该引用指向了一个新的对象的内存地址),那么是不会影响到之前方法外的那个引用的,所以修改后会发现2个引用所指向的对象不同了

3)而如果对象引用参数前加上了ref,那么方法参数所传递的不再是引用的副本,而是引用的地址了(即通过引用的地址找到引用,再读出引用里保存的内存地址值,再根据则个地址值去找到真正要操作的对象),所以如果此时你再修改这个引用的值时,会根据引用的地址找到方法外的那个引用,然后修改其内容,所以会发现方法外的引用也会指向新的对象了

 

四、代码示例说明三点注意

1、测试代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test_List : MonoBehaviour
{

    List<string> list_1 = null;
    List<string> list_2 = null; 
    List<string> list_ref_3 = null;
  


    // Start is called before the first frame update
    void Start()
    {
        list_1 = new List<string>();
        list_2 = new List<string>();
        list_ref_3 = new List<string>();
        List<string> copy_ref = list_ref_3; // 复制一个引用

        ModifyList_1(list_1);
        ModifyList_2(list_2);
        ModifyList_ref_3(ref list_ref_3);

        Debug.Log("list_1.Count: " + list_1.Count); // 3
        Debug.Log("list_2.Count: " + list_2.Count); // 0

        // list这个引用已经在ModifyList方法里被修改了,指向的是在ModifyList方法里新new出来的对象了
        Debug.Log("list_ref_3.Count: " + list_ref_3.Count); // 3
        // 复制的这个引用仍然指向原来最早的那个List
        Debug.Log("copy_ref.Count: " + copy_ref.Count); //0
    }



    // 1)list类型是引用类型
    private void ModifyList_1(List<string> list)
    {
        // 这里的list其实已经是一个引用副本了,但是所指向的内存地址仍然是原本方法外面的对象的,所以后面用该引用的Add方法所操作的,仍然是原本方法外面的对象的内存数据
        list.Add("13");
        list.Add("24");
        list.Add("34");
    }

    //2)引用本身是类似于一个“保存地址的值变量”
    //    所以从方法外部传入引用到方法里,那么其实引用本身
    //    是复制了一份副本来给方法里使用的,只是说这个复制
    //    的引用副本和之前的引用的内容(也就是所指向的对象内存地址)
    //    是一样的,所以通过引用操作对象的数据时,可以看到2个引用都操作
    //    的同一个对象;但如果你是修改了引用副本本身的值内容(将该引用指向了
    //    一个新的对象的内存地址),那么是不会影响到之前方法外的那个引用的,
    //    所以修改后会发现2个引用所指向的对象不同了
    private void ModifyList_2(List<string> list)
    {
        // 这里其实已经将引用指向了新的内存地址,所以后续的Add操作是在操作新对象的内存数据,而原来方法外的对象其实是没有受到影响的
        list = new List<string>();
        list.Add("13");
        list.Add("24");
        list.Add("34");
    }

    //3)而如果对象引用参数前加上了ref,那么方法参数所传递的不再是
    //    引用的副本,而是引用的地址了(即通过引用的地址找到引用,
    //    再读出引用里保存的内存地址值,再根据则个地址值去找到真正要操作的对象),
    //    所以如果此时你再修改这个引用的值时,会根据引用的地址找到方法外的那个引用,
    //    然后修改其内容,所以会发现方法外的引用也会指向新的对象了
    private void ModifyList_ref_3(ref List<string> list)
    {
        // 因为有ref,所以这里其实已经将方法外原本的那个引用也指向了新的内存地址,所以后续的Add操作是在操作新对象的内存数据,并且方法外原本的那个引用也指向了这个新的对象
        list = new List<string>(); 
        list.Add("13");
        list.Add("24");
        list.Add("34");
    }
}

 

2、运行结果

List路径传参java list传值_C#