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

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

  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关键字:

  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用作引用类型。

  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方法作如下修改;

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

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

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

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

  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引用,而不是其副本。

C#引用传递的更多相关文章

  1. Java 为值传递而不是引用传递

    ——reference Java is Pass by Value and Not Pass by Reference 其实这个问题是一个非常初级的问题,相关的概念初学者早已掌握,但是时间长了还是容易 ...

  2. call_user_func()的参数不能为引用传递 自定义替代方法

    php手册 中关于 请注意,传入call_user_func()的参数不能为引用传递. 关于这个情况的解释,可自己搜索.我们可以自己定义一个函数解决这样的问题,实例如下: <?php ini_s ...

  3. [转] C++的引用传递、指针传递参数在java中的相应处理方法

    原文出处:[http://blog.csdn.net/conowen/article/details/7420533] 首先要明白一点,java是没有指针这个概念的. 但是要实现C++的引用传递.指针 ...

  4. python 引用传递与值传递

    https://taizilongxu.gitbooks.io/stackoverflow-about-python/content/16/README.html 1.也就是如果传可变对象,就是引用传 ...

  5. java是值传递还是引用传递

    首先写一个简便的Employee,以便测试使用. class Employee { private String name; public Employee(String name) { this.n ...

  6. Java中值传递和引用传递的概念

    很多书中都提到了在Java中只存在值传递,但是今天在一个NanoHTTPD的源码中看到这样一段: if (qmi >= 0) { decodeParms(uri.substring(qmi + ...

  7. Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义

    一.Java中什么叫做引用类型变量?引用:就是按内存地址查询       比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...

  8. java关于值传递和引用传递的有趣试验

    上代码: public class Demo { public static void main(String[] args) { test_1(); test_2(); } public stati ...

  9. java中值传递和引用传递

    最近工作中使用到了值传递和引用传递,但是有点懵,现在看了下面的文章后清晰多了.一下是文章(网摘) 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...

  10. Java中的值传递和引用传递

    这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ...

随机推荐

  1. 12 Useful “df” Commands to Check Disk Space in Linux

    On the internet you will find plenty of tools for checking disk space utilization in Linux. However, ...

  2. UVa 11526 H(n)

    题意: long long H(int n){ long long res = 0; for( int i = 1; i <= n; i=i+1 ){ res = (res + n/i); } ...

  3. UVALive 3211 Now or later(2-sat)

    2-sat问题,一种在两种可能性中选择必然关系的问题. 推荐两篇论文,也是学2-sat公认比较好的材料.前者较好理解,后者需耐心看. http://www.google.com.hk/url?sa=t ...

  4. HTMLayout界面CSSS样式解析笔记

    HTMLayout学习笔记 by BBDXF 一.界面篇 学习界面需要有一定的HTML.CSS认知,如果你问为什么,那就当我白说. 由于界面库官方没有给一个完善的User guide,所有的学习都靠自 ...

  5. DataTables ajax重新加载数据

    传数据给后台返回数据,最开始的办法是 重新生成一个datatable对象,但是在每次点击刷新时都会有闪动的现象,而且代价很高.理想中应该仅仅更新数据. 最后在文档中查到一个插件fnReloadAjax ...

  6. 【大数加法】POJ-1503、NYOJ-103

    1503:Integer Inquiry 总时间限制:  1000ms 内存限制:  65536kB 描述 One of the first users of BIT's new supercompu ...

  7. Oracle 课程八之性能优化之10053事件

    一. 10053事件 当一个SQL出现性能问题的时候,可以使用SQL_TRACE 或者 10046事件来跟踪SQL. 通过生成的trace来了解SQL的执行过程. 我们在查看一条SQL的执行计划的时候 ...

  8. .net-C#代码判断

    ylbtech-doc:.net-C#代码判断 C#代码判断 1.A,C#代码判断返回顶部 01.{ C#题目}public static void Main(string[] args){     ...

  9. codeforces 681D Gifts by the List dfs+构造

    题意:给你一个森林,表示其祖先关系(自己也是自己的祖先),每个人有一个礼物(要送给这个人的固定的一个祖先) 让你构造一个序列,使得的对于每个人,这个序列中第一个出现的他的祖先,是他要送礼物的的那个祖先 ...

  10. 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)

    转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...