C#的引用类型和值类型

无论学习C,C++还是C#,都有人在引用上迷糊。在这里我就给大家说明一下引用。为了便于观看,我会通过例子和示意图来说明。

先来了解一下,什么是值类型,什么是引用类型。

值类型:

int i = 50;   
int i_copy = i;


i和i_copy分别是两个不同的变量,占用了两个不同的空间,改变一个不会造成另一个的改变。

示例代码:

  static void ttt(int i1)
        {
            Console.WriteLine("函数内i1重新赋值前 i1 = " + i1);
            i1 = 2;
            Console.WriteLine("函数内i1重新赋值后 i1 = " + i1);
        }
        static void Main(string[] args)
        {
            int i = 50;
            Console.WriteLine("函数调用前         i = " + i);
            ttt(i);
            Console.WriteLine("函数调用后         i = " + i);
        }



自定义了一个类A

代码如下

class A
    { 
        public int a;
        public A(int par)
        {
            a = par;
        }
    }

引用类型:

A a1= new A(50);
            A a2 = a1;


a1是一个引用,存放的不是具体的值,而是一个地址变量,指向new出来的一个对象的地址,这个对象在堆中存放。a2也是一个引用,把a2 = a1,是把a1中存放的地址变量赋值给a2,这样a2也指向了在堆中new出来的那个对象。如果改变任何一个的数值,改变的是堆中的数据,另一个的值也会改变。

示例代码:

static void sss(A a2)
        {
            Console.WriteLine("函数内a2.a重新赋值前 a2.a = " + a2.a);
            a2.a = 2;
            Console.WriteLine("函数内a2.a重新赋值后 a2.a = " + a2.a);
        }
       
        static void Main(string[] args)
        {
            A a1 = new A(42);
            Console.WriteLine("函数调用前           a1.a = " + a1.a);
            sss(a1);
            Console.WriteLine("函数调用后           a1.a = " + a1.a);
        }



通过上面可以看出,int定义的是一个值类型,而自定义的类在定义变量时,是引用。

如果我们想将int类型的变量像自定义类一样,在函数中通过引用传递。该如何呢?

我们可以用在参数传递时加ref

示例代码

 static void ttt1( ref int  i1)
        {
            Console.WriteLine("函数内i1重新赋值前 i1 = " + i1);
            i1 = 2;
            Console.WriteLine("函数内i1重新赋值后 i1 = " + i1);
        }
        static void Main(string[] args)
        {
           int i = 50;
           Console.WriteLine("函数调用前         i = " + i);
           ttt1(ref i);
           Console.WriteLine("函数调用后         i = " + i);

}


调用时和定义时都要加ref

此时,被调函数的值改变,主函数的值也被改变。


无论是通过引用传递还是值传递,都要将实参进行初始化才行使用,如果不初始化,编译阶段会报错。

我们可以用用out替代ref


static void ttt2(out int i1)
        {
            i1 = 2;
            Console.WriteLine("函数内i1赋值后 i1 = " + i1);
        }

static void Main(string[] args)
        {
           int i ;
        
           ttt2(out i);
           Console.WriteLine("函数调用后         i = " + i);

}

这种情况下,调用前可以不对实参初始化,无论对不对实参初始化,再函数内,必须形参初始化才能使用,不然会报错。形参在函数体内的改变,会影响函数体外的实参的改变。这种情况下传递的是引用。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值