您当前的位置: 首页 >  c#

光怪陆离的节日

暂无认证

  • 3浏览

    0关注

    1003博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C#值传递与引用传递的区别和用法

光怪陆离的节日 发布时间:2022-10-15 08:14:32 ,浏览量:3

1 类类型的数据传递

C#和C++ 一样,有值传递和引用传递。例如下面的代码

Person p1 = new Person(); p1.Name = “张三”;

Person p2 = p1; p2.Name = “李四”;

Console.WriteLine(p1.Name); 把对象p1赋值给p2, 此时p2修改Name属性,那么p1的Name属性也被修改了,类是 引用类型,一个对象的修改可能会涉及到其它对象的修改。但是对于string类型又不同,string具有不可变性,例如下面的代码

//字符串的不可变性 string str1 = “abc”; string str2 = str1; str2 = “dfg”;

Console.WriteLine(“str1 = {0}”, str1); Console.WriteLine(“str2 = {0}”, str2); str1赋值给str2,修改str2的值,并不会 修改str1的值,这是string和其它类的区别,string赋值时会重新在堆上分配空间,之前的值依然存在。

2 函数引用传参

(1)基本数据类型

public static void TestNum(ref int num) //相当于C++的引用传参 { num += 10; } 如果在函数参数的前面加了ref关键字,那么此时就和C++的引用传参是一样的,区别是C#在调用时, 实参前面也要加 ref修饰,不然会有语法错误。

(2)类类型做形参

public static void TestClass(Person p) //相当于C++的引用传参 { p.Name = “赵六”; } 此时传入对象,会修改对象的属性。

3 返回ref类型的数组项

例如下面的代码

using System;

namespace ref返回 { class Program { public static ref int Test(int[] array) { return ref array[0]; }

    static void Main(string[] args)
    {
        int[] array = { 5, 80 };
        ref int tmp = ref Test(array);

        Console.WriteLine("{0}, {1}", array[0], array[1]);

        tmp = 0;  //修改这个引用后,数组对应的元素值也被修改了

        Console.WriteLine("{0}, {1}", array[0], array[1]);

        Console.ReadKey();
    }
}

} 函数Test返回的是ref类型的数组项,当调用Test函数后,如果外部修改返回值,对应的数组项也会被修改。 对于值类型它在进行值得传递的时候传递都是它的数值,但是引用类型传递的都是传递引用,对于常见的引用类型,比如:

xxx a=new xxx();

当我们将a赋值到另一个xxx的对象(比如对象b),那么我们在利用对象b去操纵与利用a去操纵是一样的,因为它们指向的是同一块堆空间。

引用类型:自定义类,数组,字符串,接口,集合

值类型:int,double,float,char,bool,decimal,enum,struct

值类型的值传递 值类型存储的地方全部都在栈上。

比如int a=10;

此时我们输入这样的语句int b=a,那么会在栈上开辟一块空间去存储a的值,然后b就是指向该栈空间。所以说值类型是值传递,因为引用类型的传递时将栈上的指针进行传递,所以传递的仅仅只是指向堆空间的指针,所以时引用传递。

String特殊的引用传递 因为String字符串有着不变性,如果我们去修改一个字符串,它的本质时开辟其他的堆空间,然后将之前的引用切断然后指向新开辟的堆空间,这就使得频繁修改字符串会导致空间的浪费。我们来看下面的例子:

String a=”aaa“

String b=a

虽然String是引用类型,但是因为修改字符串的本质都是新开辟堆空间,然后修改引用,那么上面的语句执行的本质是在堆上开辟一个新空间,然后将b指向新开辟的空间,里面的值是“aaa”。

ref和out 因为值类型在作为参数传入的时候,传递的是一个新的栈空间,那么传入后,无论在方法的内部如何修改传入的参数,都无法改变外部的值类型变量,所以我们可以使用ref和out参数去修饰,使得传入的参数不是就的栈空间,而是值对象指向的那块栈空间,这样在方法内部修改,操作后就可以影响外部参数。

out强调传入的是一个没有初始化的值类型。

而ref强调传入的是一个初始化后的值类型。

关注
打赏
1665731445
查看更多评论
立即登录/注册

微信扫码登录

0.0405s