看如下代码:
 
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. win7 mysql 数据库轻松实现数据库定时备份

    本地备份: 第一步: 安装一个mysql. 第二步: 在命令行中配置mysql 打开环境变量将mysql 安装路径配置到path中 第三部: cmd 中输入:mysqldump -uroot -p12 ...

  2. word中批量转换字母数字为Times New Roman

    通常撰写论文时,英文与中文的格式会区分开,但是一个个修改会比较费时,可以通过替换功能实现.此处以word2003为例. 1.选择 编辑→替换 界面.在“查找内容”文本框中输入"[0-9a-z ...

  3. css 块状元素与行内元素(内联元素)的理解

    块状元素: 它一般是其他元素的容器元素,可以容纳块状元素和行内元素,它默认是不会和其他元素同一行的,即相当于两个块状元素写一起是垂直布局的.最常用的是div和p 行内元素: 行内元素又称内联元素,它只 ...

  4. 【转】char*,string,CString,int,char[]之间的转换

    CString 头文件#include <cstring>.CString 转char * CString cstr;  ..data(),返回没有”/“的字符串数组..c_str(),返 ...

  5. python简单分布式demo

    A服务器是master,B服务器为worker, A服务器上执行taskManger.py # coding:utf-8 import random,time,Queue from multiproc ...

  6. 【PHP】学习中遇到的php方法

    [1]range()快速创建一个范围内数组 <?php range(0,20); 创建一个包含从 "0" 到 "20" 之间的元素范围的数组: range ...

  7. 程序管理与SElinux

    一.程序: 1.在Linux中,触发任何一个事件是,系统都会将他定义为一个程序,并且给予这个程序一PID,同时依据启发这个程序的使用者与相关属性关系,给予这个PID一组有效的权限设定,从此以后,这个P ...

  8. python绘制图形(Turtle模块)

    用python的Turtle模块可以绘制很多精美的图形,下面简单介绍一下使用方法. 需要用到的工具有python,python 的安装这里就不再细说.自行搜索. from turtle import ...

  9. Lucene.net(4.8.0) 学习问题记录五: JIEba分词和Lucene的结合,以及对分词器的思考

    前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...

  10. SpringBoot与Mybatis整合方式01(源码分析)

    前言:入职新公司,SpringBoot和Mybatis都被封装了一次,光用而不知道原理实在受不了,于是开始恶补源码,由于刚开始比较浅,存属娱乐,大神勿喷. 就如网上的流传的SpringBoot与Myb ...