浅析C#值传递与引用值传递

先上一段代码。

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的参数进行值传递呢?对于结构里面的非引用部分,肯定是不会影响。对于引用部分,通过实验,也是不影响的。

你可能感兴趣的:(值传递)