看如下代码:
 
void Test(T t);
void Test(ref T t);
当T是值类型的时候,很好判断,第一种并不能改变方法外变量的值,需要第二种方法才可以。通过查看IL代码,可以看到第二种方法是直接传的原变量T的地址,这里并没有发生装箱行为(如果发生装箱的话,会在堆中新建一个T变量,这也不会改变原来T变量的值,因此不成立)。
当T是引用类型的时候,第一种其实也相当于值传递,不过是原变量的地址给了t这个变量,最终操作的是同一个对象。而用ref的话,就没有地址复制这一步,直接把原变量的地址传了进去,当然结果都是一样的。
 
*但如下情况需要注意的是
 
        static void Main(string[] args)
{
UserInfo info = new UserInfo();
Console.WriteLine("调用方法之前哈希code:{0}", info.GetHashCode());
Reset(info);
Console.WriteLine("调用方法之后哈希code:{0}", info.GetHashCode());
Console.ReadKey();
} public static void Reset(UserInfo info)
{
Console.WriteLine("Reset赋值之前的哈希code:{0}", info.GetHashCode());
UserInfo user = new UserInfo();
info = user;
Console.WriteLine("Reset赋值之后哈希code为{0}", info.GetHashCode());
}
查看输出:
 
可以看到,如果不使用ref,传入的是引用的一个副本,这个副本存储的地址和传入的变量是一致的,引用同一个对象,因此哈希值相同。
给这个副本赋新的变量地址后,哈希值发生了改变。
但这总归是发生在复制的副本身上,原来的变量,哈希值未改变。
值得注意的是,如果info里面的参数,在Reset中info = user这个语句之后,发生了任何改变,都已经不会体现到Reset外围。
比如info.userName = "aa";
在info = user语句之后,加入 info.userName = "cc"。
在最后Console.ReadKey之前输出userName, 它还是"aa"。
Reset里面的info已经完全指向另外一个对象了。
 
如果我们在Reset方法的参数之前加上ref
 
那就是直接使用外围变量的值了,任何操作都直接影响外围传入的变量。包括上述说的userName也会被改变。整个来说就是原来变量地址上的类被换了一个。
 
综合来说,如果只是改变原有变量的内部变量值之类的操作,加不加ref都一样,当涉及到new赋值操作的时候,除非是刻意需要这么做,不然推荐加ref。

C#中引用变量是否应该加ref?的更多相关文章

  1. sed中引用变量

    sed 中引用变量 eval sed 's/string/$REPLACE/g' file awk 中引用变量 awk 在匹配字符串的时候,有时候需要需要引用变量. $pid= eval " ...

  2. awk中引用变量使用单引号''

    举例如下 who命令输出第一列 (1)第一种情况不使用引号 # i=1;who | awk '{print $${i}}' 输出如下: awk: {print $${i}} awk:          ...

  3. linux中环境变量和系统加载环境变量的顺序

    一.系统环境变量: /etc/profile :这个文件预设了几个重要的变量,例如PATH, USER, LOGNAME, MAIL, INPUTRC, HOSTNAME, HISTSIZE, uma ...

  4. 引用变量类型的加载顺序(类名+引用名=new +类名();)

    程序如下: 运行结果如下: 以上结果说明:同一个引用名称(可以把它当做变量的一种类型)可能指代不同的对象,依据同一个引用是否处于同一个初始化的层次,决定是否在完成: static Cup c1=new ...

  5. 为什么在匿名内部类中引用外部对象要加final修饰符

    当所在的方法的形参需要被内部类里面使用时,该形参必须为final. 为什么必须要为final呢? 首先我们知道在内部类编译成功后,它会产生一个class文件,该class文件与外部类并不是同一clas ...

  6. python,在路径中引用变量的方法

    fr = open('E:\\pyCharm\\LogisticRegression\\1\\'+变量+'.txt')

  7. with open()函数中,如何在文件名设置中引用变量(python)

    name = "wangyang" age = " with open("C:/Users/mike1/Desktop/name_age.txt", ...

  8. C++引用变量(转)

    引用变量 c++中引用变量的使用: 定义: int rate=80; int  & pt=rate 1.pt 是引用变量,申明引用变量时必须将其初始化.pt 和rate 的值指向相同的内存变量 ...

  9. PHP关于foreach使用引用变量的坑

    写PHP好多年,但仍然会犯低级错误,今天遇到个 foreach中引用变量时的坑,PHP版本为 5.6.12 代码如下: <?php $arr = ['a', 'b', 'c', 'd', 'e' ...

随机推荐

  1. No grammar constraints (DTD or XML schema).....两种解决方法

    方法一:常用方法   关闭XML验证 工具栏:windows => preferences => xml => xml files => validation => In ...

  2. javascript对象的标签

    [[proto]]标签 [[class]]标签 [[class]] 标签,代表这对象是哪个类型的.在js中不能直接访问到.可以通过Object.prototype.toString.call(obj) ...

  3. underscore.js 源码阅读 准备

    本次阅读是初次阅读源码,参考了以下几篇文章: https://github.com/hanzichi?language=javascript&page=5&tab=stars http ...

  4. Storm集群安装与部署

    准备 1.三台虚拟机 192.168.1.128 Nimbus 192.168.1.131 Supervisor 192.168.1.132 Supervisor 2.JDK1.8 3.Zookeep ...

  5. 一个自己稍作修改了的美赛论文LaTeX模板

    原模板(5.0)来自LaTeX工作室(latexstudio.net),我按照比赛规范做了一点小小的修改(5.0y),并加上了比原来更详细一些的注释,方便使用. 仅仅分享一下方便大家使用,模板的原创者 ...

  6. finally中关闭资源

    对finally中关闭资源是否还要使用try...catch老是感到迷惑,现在存个例子,省的忘了 public StringBuilder readTxtFile(File file){ String ...

  7. libev学习笔记

    转 libev的使用--结合Socket编程 作者:cxy450019566 之前自己学过一些libev编程的基础,这次写压测刚好用上了,才算真正动手写了些东西,在这里做一些总结.写这篇文章是为了用浅 ...

  8. Visionpro学习笔记 :QuickBuild-Based Application Run-Once Button

    1) Creating a Run-Once Button 通过JobManager调用VisionPro文件.所有的过程放到一个Try/Catch块中. Private Sub RunOnceBut ...

  9. awk批量处理文件夹中所有文件

       #c=``     done

  10. 面向对象_03【关键字:final使用】

    final关键字:可修饰类.变量名和方法1,final修饰的类不能被继承2,final修饰的变量(成员.局部)是常量,只能赋值一次.3,final修饰的方法不能被子类重写Example:一:修饰类 / ...