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

38 篇文章 17 订阅

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、运行结果

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
委托和事件在C#中是密切相关的概念。委托是一种类型,它可以持有对一个或多个方法的引用,并允许将这些方法作为参数传递、存储和调用。委托提供了一种方便的方式来实现事件的订阅和通知机制。 事件是委托的一种特殊用法,它是一种在类中定义的特殊成员,用于通知其他对象发生了某个特定的动作或状态的变化。事件基于委托和事件参数类(通常是EventArgs的派生类)来实现。在声明事件时,需要先定义一个委托类型,然后使用event关键字进行事件的定义。 事件的发布者是包含事件的类,它负责触发事件并通知订阅者。在发布者类中,通过调用委托实例来触发事件。通常,事件的触发方法会检查事件是否有订阅者,如果有,则通过调用委托实例来触发事件。 总结来说,委托是一种类型,用于持有对方法的引用,而事件是委托的一种特殊用法,用于实现订阅和通知机制。委托和事件在C#中常常一起使用,以实现松耦合的对象间通信。 #### 引用[.reference_title] - *1* [C#事件与委托之间的关系](https://blog.csdn.net/qq_42672981/article/details/110186571)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [C#中的委托和事件](https://blog.csdn.net/qq_41872328/article/details/121333505)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [C#Unity中的委托和事件机制](https://blog.csdn.net/qq_60125117/article/details/130224009)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仙魁XAN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值