先上一段代码。
using UnityEngine; using System.Collections; public class TypePassing : MonoBehaviour { public Dog dog = new Dog (1, "xiaobai") ; //调用默认构造函数给struct里所有字段一个缺省值,对dog来说是null public Cat cat = new Cat ();//貌似在这里不能直接赋值dog属性 int i = 0; void Start(){ cat = new Cat (dog, 1, "xiaohua"); ParameterPass (dog); Debug.Log (dog.number + dog.name);//1xiaobai ParameterPass (out dog); Debug.Log (dog.number + dog.name);//8yuzi ParameterPass (i); Debug.Log ("i="+i);//i=0 ParameterPass (ref i); Debug.Log ("i="+i);//i=2 Debug.Log (cat.name + cat.number + cat.dog.name);//xiaohua1xiaobai ParameterPass (cat); Debug.Log (cat.name + cat.number + cat.dog.name);//xiaohua1xiaobai } //不带ref的引用传递,只有在改变对象的字段时才会影响原来对象 //推测是一个新的变量指向原来的地址,对值类型直接copy一份过来 void ParameterPass(Dog dog){ dog = new Dog(6,"xiaolong"); } //使用ref的传递是彻底的引用传递,无论对参数进行什么操作都将影响原来对象 /*void ParameterPass(ref Dog dog){ dog = new Dog(7,"feizi"); }*/ //out与ref类似,不做任何复制,直接传递引用 //out与ref不能重载,与不带out、ref的方法能重载 void ParameterPass(out Dog dog){ dog = new Dog(8,"yuzi"); } void ParameterPass(int i){ i = 1; } void ParameterPass(ref int i){ i = 2; } void ParameterPass(Cat cat){ cat.name = "simao"; cat.dog = new Dog(8,"yuzi"); cat.dog.name = "feizhu"; } } public class Dog{ public int number; public string name; public Dog(int number, string name){ this.number = number; this.name = name; } } public struct Cat{ public Dog dog; public int number; public string name; public Cat(Dog dog,int number,string name){ this.dog = dog; this.number = number; this.name = name; } }
C#的值类型包括struct和enum,我们常用的int、byte等是一种特殊的值类型,声明一个int类型,实际上是声明一个System.Int32结构类型,所有的值类型都隐性继承自System.ValueType。C#的引用类型包括类、接口和委托。
传递值类型的参数就是直接把该值复制一份传递给方法,传递引用类型的参数,可能是传递了一个指向该对象的新的变量给方法使用。对该变量进行赋值是不会影响原来对象的,但是改变该变量的字段属性则会影响原来对象,原因该变量与方法外部变量指向了堆内的同一个对象。
当使用ref和out的时候,传递的就是原来的变量。对参数进行任何改动,就相当于直接对原来的变量进行改动。
那么当结构类型里面包含引用类型,使用不带ref的参数进行值传递呢?对于结构里面的非引用部分,肯定是不会影响。对于引用部分,通过实验,也是不影响的。
时间: 2024-10-24 21:34:16