C#引用传递

学过C#的人都知道,通过或通过引用,值类型和引用类型都可以作为方法参数传递。在C#中,不管是值类型或者是引用类型,所有方法参数在默认情况下是通过值传递的。

1)通过值传递值类型
在通过值传递作为方法参数的变量时,传递给方法的是数据副本。在方法中对该数据的任何修改都不会对初始值有任何影响
C#如下代码:

[csharp] view plaincopy

  1. using System;
  2. class MyExecutableClass
  3. {
  4. static void Main(string[] args)
  5. {
  6. int value=50;
  7. DoSometing(value);
  8. Console.WriteLine(value);
  9. }
  10. static void DoSomething(int parameter)
  11. {
  12. parameter=100;
  13. }
  14. }

程序的输出为50.也许你会感到奇怪,为什么不是100呢?因为变量value是通过值而不是引用传递的。我们不需要添加任何特殊的关键字,而是依赖于C#的默认行为,通过值传递值类型。

2)通过引用传递值类型
通过引用传递值类型,也就是说传递值(变量)的引用。如果传递引用的话,那么无论在程序的什么地方作改变的话(可能是在另一个方法、属性中,甚至是另一个对象中),都会改变使用改引用的值。对方法中任何参数的改变都将影响方法的返回值。
在C#中,通过引用传递是通过ref关键字实现的,必须按如下所示将ref关键字添加到方法定义中:
static void DoSomething(ref int parameter)
传递参数时,必须使用ref关键字。
DoSomething(ref value)
下面的代码演示了如何对值类型使用ref关键字:

[csharp] view plaincopy

  1. using System;
  2. class MyExecutableClass
  3. {
  4. static void Main(string[] args)
  5. {
  6. int value=50;
  7. DoSomething(ref value);
  8. Console.WriteLine(value);
  9. }
  10. static void DoSomething(ref int parameter)
  11. {
  12. parameter=100;
  13. }
  14. }

结果正如你所料,输出为100.

3)通过值传递引用类型
一般来说,通过值传递意味着传递存储在栈中的值。对于引用类型来说,存储在栈上的值表示对
内存中对象实际位置的引用。因此,如果通过值传递引用类型,就意味着传递的是对象的引用(它的堆栈)
.使用该引用作的改变最终会改变堆中的同一对象。
通过值传递引用类型不像通过值传递值类型---它更像通过引用传递值类型。在如下代码中,
我们将Person用作引用类型。

[csharp] view plaincopy

  1. using System;
  2. class MyExecutableClass
  3. {
  4. static void Main(string[] args)
  5. {
  6. Person person=new Person(50);
  7. DoSomething(person);
  8. Console.WriteLine(person.Age);
  9. }
  10. static void DoSomething(Person somePerson)
  11. {
  12. somePerson.Age=100;
  13. }
  14. }
  15. class Person
  16. {
  17. public int Age;
  18. public Person(int Age);
  19. {
  20. this.Age=Age;
  21. }
  22. }

运行程序,可以发现输出值为100.

如果对DoSometing方法作如下修改;

[csharp] view plaincopy

  1. static void DoSomething(Person somePerson)
  2. {
  3. somePeron=new Person(100);
  4. }

重新运行程序,发现输出为50.这是因为我们并没有将引用传递给方法?
答案是:不,我们确实发送了引用。引用类型有两个元素---引用和对象。现在,在
调用DoSomething()方法时,我们创建了一个引用副本,它仍然指向同一对象,因此,对对象的改变会影响主程序。而对引用的改变则不会,在方法结束时,消失的只是引用的副本。
1。在使用somePerson.Age属性改变年龄时,我们改变的是对象

2。但接下来是创建一个新对象,改变引用来指向它---对引用的改变将会丢失。
应该怎么做呢?方案就是通过引用传递引用类型,那样作的话,如果改变somePerson所存储的引用,那么另一个“父”引用会自动更新。听起来很混乱,下面再讨论。

4) 通过引用传递引用类型
我们知道,在通过值传递引用类型时,我们传递对内存中对象位置的引用。而通过引用传递引用类型时,我们将传递引用的引用。

正如我们所看到的,通过值传递引用类型并不适合于所有情况---特别是需要改变引用以指向新对象时。
下面例子就是说明通过引用传递就很有用。

[html] view plaincopy

  1. <pre name="code" class="csharp"></pre><pre name="code" class="csharp">using System;
  2. class MyExecutableClass
  3. {
  4. static void Main(string[] args)
  5. {
  6. Person person=new Person(50);
  7. DoSometing(ref person);
  8. Console.WriteLine(person.Age);
  9. }
  10. static void DoSometing(ref Person somePerson)
  11. {
  12. somePerson=new Person(100);
  13. }</pre><pre name="code" class="csharp">} </pre>
  14. <pre></pre>

这次输出为100;person变量实际上对堆上Person对象的引用。在调用DoSomething()时,编
译器创建了对Person引用的引用(而不是对Person对象的引用).在DoSometing()方法中,somePerson是Person引用的
引用,而Person引用堆上的对象。然而,DoSomething()知道值是通过引用传递的,因此对somePerson的任何改变实际上是改变了
person。结果就是somePerson的行为就好像它是person引用,而不是其副本。

时间: 2024-11-06 03:58:13

C#引用传递的相关文章

引用传递

引用传递的本质就在于别名,而这个别名只不过是放在了栈内存之中,既:一块堆内存可以被对个栈内存所指向 举例: Person per1 = new Person(); per1.name = "小于子"; per1.age = 30; Person2 oper2 = per1; oper2.name = "狗剩"; 在程序开发中,所谓的垃圾空间指的是没有任何栈内存指向的堆内存空间,所有的垃圾空间将不定期被java的垃圾收集器(GC.Garbage Collector)进

值传递 引用传递

方法参数传递有2种方式: 值传递和引用传递. 值传递: 默认都是值传递.值传递有2种,值类型和引用类型的.实质是复制栈中的值. 值类型的值传递:栈中的值就是实际值. 引用类型的值传递:栈中的值是内存堆中地址. 引用传递: 参数前加ref的为引用传递,引用传递有2种,值类型和引用类型的.实质就是传递自己本身,只是多了个别名.

java 引用传递和值传递

1.为什么要分值传递和引用传递: 基本类型存在在栈中,复合类型(对象)存在堆中.操作栈的速度要快于堆,且对象的复制相比基本类型不仅浪费内存而且速度比较慢. 从这里就可以看出来:对象是按照引用传递(数据库事务封装Connection对象传递的时候最能体现这点):基本类型是按照值传递. 2.那为什么String类型传递后会表现的值传递的特性:这并不是由于值传递而导致的,而是由于String类的不可变性(只读特性)导致的.String类型按照引用传递,但是一旦改变了,就变成新的对象了,原来引用指向的对

引用传递应用实例

class Member{ private int id; private String name; private Car car;//表示属于人的车 public Member(int id,String name){ this.id=id; this.name=name; } public String toString(){ return "编号:" + this.id + ",名字:" + this.name; } public void setCar(C

java值传递or引用传递解惑

java中的參数传递本质上仅仅有值传递,无论你传的是什么,传过去的都仅仅是一个副本而已,这个副本作为方法的局部变量保存在栈中. 1.假设參数类型为基本数据类型,改动这个值并不会影响作为參数传进来的那个变量,由于你改动的是方法的局部变量,是一个副本. 2.假设传的是一个对象的引用,也是一样的,也是一个副本,可是这个副本和作为參数传进来的那个引用指向的是内存中的同一个对象,所以你通过这个副本也能够操作那个对象.可是假设你改动这个引用本身,比方让他指向内存中的另外一个对象,原来作为參数传进来的那个引用

const 值传递和引用传递

const关键字,我们用const修饰的变量表明该变量的值以后不可以修改,即相当于常亮,并且在定义的时候应当初始化. 如:const int n = 0; 这和 int const n = 0;是等价的 extern修饰:extern的原理很简单,就是告诉编译器:"你现在编译的文件中,有一个标识符虽然没有在本文件中定义,但是它是在别的文件中定义的全局变量,你要放行!" 所以和一般的extern用法没有区别: file1 extern const int n = 1; //定义并初始化

java的引用传递

最近看着李兴华讲师的java视频教程学习java,关于java引用传递方面的知识的总结. 基础知识 java的常用内存空间 栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址) 堆内存空间:保存具体对象的具体属性内容. 全局数据区:保存static类型的属性 全局代码区:保存所有的方法定义 实例分析 class Person { private String name; private int age; private static String city = "北京&qu

值传递,指针传递;引用传递(c++独有)本质

要理解值传递.指针传递和引用传递的区别,主要要理解函数的实参和形参,函数的作用域(自动变量.栈),内存的布局以及指针和引用的特点.这里主要总结三种参数传递方式使用的主要场合. 值传递:只给函数提供输入值,需要复制开销,大对象很少使用值传递. 指针传递:可以改变指针指向内容的值,但是不能改变指针本身,无需复制开销.如果需要改变指针本身,可以使用二重指针或者指针引用. 引用传递:除了提供输入值外,还返回操作结果,无需复制开销. #include<stdlib.h> //值传递,函数体内变量n是参数

Java中的值传递和引用传递

解释 1.Java中有没有引用传递? 答:Java中只有按值传递,没有按引用传递! 2.当一个对象被当作参数传递到一个方法中后,在此方法中可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 答:是值传递. Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言).如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的,如果在函数中改变了副本

c# 值类型与引用类型 值传递与引用传递

值类型与引用类型: 值类型 :1.值类型大小固定.存储在栈上.  2.不能继承,只能实现接口 3.派生自valuetype int double char float byte bool enum struct decimal 引用类型:1.在栈上存储了一个地址实际存储在堆中,大小不固定. 2.数组.类.接口.委托 string 数组 类 接口 委托 值传递与引用传递: 值类型按值传递.值类型按引用传递.引用类型按值传递.引用类型按引用传递. 值传递:默认传递都是值传递 ,把栈中内容拷贝一份引用