C#类型有值类型与引用类型之分:
值类型:既可以分配在栈上也可以分配在堆上。像 bool/int/float这些基础数据类型都是值类型。它们通常是分配在栈上,但一旦值类型包括在引用类型中,如类或数组时,表明该值对于栈而言太大,或存在的时间需要比当前的作用域更长,因而必须分配在堆上,与包含它的引用类型绑定在一起。
引用类型:由于引用类型的复杂性、大小和使用方式,它们会(或需要)在内存中存在一段时间,像大的数据集和从类实例化的任何类型的对象、数组(不管是值类型的数组还是引用类型的数组)、委托等。它们才会被GC标记进行回收处理。被引用的对象只有总引用数量为0时,才会被GC回收。
值类型和引用类型最大的区别是引用类型是指向内存中其他位置的指针。
值得注意的是,函数参数的按值传递和按引用传递与值类型和引用类型的概念不是同一回事儿。
按值传递:将对象的数据作为参数传入另一个函数时,称为按值传递;
按引用传递:将对象的引用作为参数传入到另一个函数时,称为按引用传递;
一般没有显示使用ref或out关键字的都是按值传递。
按值传递可以再细分为:值类型按值传递和引用类型按值传递2种;
按引用传递也可以再细分为:值类型按引用传递和引用类型按引用传递2种;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/*
* Author:W
* 1.参数的按值传递与按引用传递4种情况
*/
public class StudentInfo
{
public int age;
}
public class FuncParamTest : MonoBehaviour {
void Start()
{
值类型:按值传递测试
//StudentInfo studentInfo = new StudentInfo();
//studentInfo.age = 2;
//ValueTypeByV(studentInfo.age);
//Debug.Log("Start age==" + studentInfo.age);
引用类型按值传递测试
//StudentInfo studentInfo = new StudentInfo();
//studentInfo.age = 2;
//RefTypeByV(studentInfo);
//Debug.Log("Start age==" + studentInfo.age);
与上面的对比知道,按值传递时,传递过去的是该引用类型实例的"引用"的一个拷贝.
//RefTypeByV2(studentInfo);
//Debug.Log("Start age2==" + studentInfo.age);
值类型按引用传递测试
//StudentInfo studentInfo = new StudentInfo();
//studentInfo.age = 2;
//ValueTypeByRef(ref studentInfo.age);
//Debug.Log("Start age==" + studentInfo.age);
//引用类型按引用传递测试
StudentInfo studentInfo = new StudentInfo();
studentInfo.age = 2;
RefTypeByRef(ref studentInfo);
Debug.Log("Start age==" + studentInfo.age);
//与上面的对比知道,按引用传递时,传递过去的是该引用类型实例的"引用"的本身.
RefTypeByRef2(ref studentInfo);
Debug.Log("Start age2==" + studentInfo.age);
}
/// <summary>
/// 值类型:按值传递
/// 按值传递时,传递过去的是该值类型"实例"的一个拷贝。
/// </summary>
/// <param name="age"></param>
public void ValueTypeByV(int age)
{
age = age + 1;
Debug.Log("值类型按值传递 age=" + age);
}
/// <summary>
/// 引用类型按值传递
/// 按值传递时,传递过去的是该引用类型实例的"引用"的一个拷贝.
///
/// </summary>
/// <param name="studentInfo"></param>
public void RefTypeByV(StudentInfo studentInfo)
{
studentInfo.age = studentInfo.age + 1;
Debug.Log("引用类型按值传递 studentInfo.age==" + studentInfo.age);
}
/// <summary>
/// 引用类型按值传递2
/// </summary>
/// <param name="studentInfo"></param>
public void RefTypeByV2(StudentInfo studentInfo)
{
studentInfo = new StudentInfo();
studentInfo.age = 100;
Debug.Log("引用类型按值传递2 studentInfo.age==" + studentInfo.age);
}
/// <summary>
/// 值类型按照引用传递:把该实例在栈上的地址,传递给了方法
/// </summary>
/// <param name="age"></param>
public void ValueTypeByRef(ref int age)
{
age = age + 1;
Debug.Log("值类型按引用传递 age=" + age);
}
/// <summary>
/// 引用类型按照引用传递
/// 只是将“该实例的引用本身”,传递给了方法
/// </summary>
/// <param name="studentInfo"></param>
public void RefTypeByRef(ref StudentInfo studentInfo)
{
studentInfo.age = studentInfo.age + 1;
Debug.Log("引用类型按引用传递 studentInfo.age==" + studentInfo.age);
}
/// <summary>
/// 引用类型按照引用传递2
/// </summary>
/// <param name="studentInfo"></param>
public void RefTypeByRef2(ref StudentInfo studentInfo)
{
studentInfo = new StudentInfo();
studentInfo.age = 100;
Debug.Log("引用类型按引用传递2 studentInfo.age==" + studentInfo.age);
}
}
值类型按值传递:值类型的实例本身的拷贝的传递
引用类型按值传递:该对象实例的引用的拷贝的传递
值类型按引用传递:该实例的地址传递
引用类型按引用传递:该实例的引用本身的传递