ref以及传值传址的理解
public class MyClass{ public int Id { get; set; } }
static void Invoke1(MyClass myClass)
{
myClass.Id = ;
}
static void Invoke2(MyClass myClass)
{
myClass = new MyClass { Id = };
}
var myClass = new MyClass { Id = };//原始值100
Invoke1(myClass);
Console.WriteLine(myClass.Id); //100变为0
Invoke2(myClass);
Console.WriteLine(myClass.Id); //依然是0
下面换一下将引用类型的参数加上ref关键字
public class MyClass{ public int Id { get; set; } }
static void Invoke1(MyClass myClass)
{
myClass.Id = ;
}
static void Invoke2(ref MyClass myClass)
{
myClass = new MyClass { Id = };
}
var myClass = new MyClass { Id = };//原始值100
Invoke1(myClass);
Console.WriteLine(myClass.Id); //100变为0
Invoke2(ref myClass);
Console.WriteLine(myClass.Id); //0变为50
- 引用类型的参数,函数中的改变不一定会影响原来的参数
- 即使是引用类型,加上ref关键字以后也可能产生不一样的结果
传过去的都是栈的副本:新的栈地址(栈的地址有改变) + 值副本(完全不变)
那么引用类型和值类型的参数传参行为是有区别的,区别在这里:
- 对于值类型:值副本就是原来的值
- 对于引用类型:值副本就是原来的堆栈地址
PS: 值类型栈上保存的值,引用类型栈上保存的托管堆的地址,真正的值在托管堆上
值类型传参对原参数无影响:栈地址和栈上的值都是副本,当然没影响
引用类型为什么有影响(不是所有情况都有影响):传过去的堆栈地址和原来的堆栈地址是同一个地址,引用类型数据在堆栈,所以操作是针对的同一个堆栈操作,堆栈值变了,原参数引用的也是这个堆栈,当然值也跟着变化。但是如果这种操作不是操作堆栈则不会影响以前的数据(比如把栈地址副本指向一个新的堆栈地址),
myClass = new MyClass { Id = 50 };
,这种操作是在堆栈上重新分配地址,然后把堆栈地址赋值给新栈副本,也就是副本栈的值不是原来的堆栈地址了,而是新的堆栈地址,那么这种改变对于原来的栈地址是没有任何影响的。
正常传参过程中值类型和引用类型内存示意图:
那么ref关键字到底是有什么作用?

ref以及传值传址的理解的更多相关文章
- [SAP ABAP开发技术总结]Form(subroutine)、Function参数传值传址
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- intent传值传对象跳转
intent传值传对象跳转 1.传值 //原activity中存入一个字段 intent = new Intent(From.this, To.class); intent.putExtra(&quo ...
- 关于c#中”ref”和”out”关键字的一些理解
一. 综述(本文内容大部分来自网络,经本人整理而成,仅供学习参考,不免理解错误,欢迎批评指正) 在c#中,方法的参数传递有四种类型: (1) 传值参数(by value) 传值参数无需额外的修饰符.传 ...
- 使用泛型元组替代out与ref形式传参
我们在开发的时候,都会常常遇到一个问题,如何为逻辑上返回多个对象设计方法签名.通常我们会想到使用out或ref修饰参数,或者麻烦些自己设定一个类型内部包含多个Object类型属性来接收多个返回值.这两 ...
- C#传真传址 结构体
1.传真 传址 namespace 传值_传址 { class Program { //格式1:无参无返 public void LeiJia() { Console.Write("请输入 ...
- 浅谈对java中传参问题的理解
之前用的c/c++比较多,在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.在网上找了找,按我之前的理解,java中传 ...
- react组件传值传方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 简谈Java传值传引用
本随笔旨在强化理解传值与传引用 如下代码的运行结果 其中i没有改变,s也没有改变. 但model中的值均改变了. i :100s :hellomodel :testchangemodel2 :ch ...
- HTTP协议GET方法传参最大长度理解误区
结论 HTTP 协议未规定GET和POST的长度 GET的最大长度是因为浏览器和WEB服务器显示了URI的长度 不同浏览器和WEB服务器,限制的最大长度不同 若要支持IE,则最大长度为2083 byt ...
随机推荐
- 版本管理工具(git)
Git是一个开源的分布式版本控制系统 工作区: 电脑目录中,git_test文件夹就是一个工作区. 版本库: 在进行git操作的时候,会生成一个隐藏目录.git,这是git的版本库,其中stage(或 ...
- day62 django入门(3)
目录 一.无名有名分组的反向解析 1 无名分组的反向解析 2 有名分组的反向解析 二.路由分发 三.名称空间(了解) 四.伪静态(了解) 五.虚拟环境(了解) 六.django版本区别 1 url的区 ...
- java 面向对象(十五):面向对象的特征三:多态性
1.多态性的理解:可以理解为一个事物的多种形态.2.何为多态性:对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)举例:Person p = new Man();Object obj ...
- OSI物理层之数据通信基础知识
@ 目录 物理层的基本概念 物理层的主要任务 数据通信的基础知识 典型的数据通信模型 相关术语 信道的基本概念 基带(base band)信号和带通(band pass)信号 几种最基本的调制方法 常 ...
- 什么是控制反转(IoC)?什么是依赖注入(DI)?以及实现原理
IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合.更优良的程序.传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试:有了 ...
- Java中使用方法的注意事项
Java方法使用的注意事项 本文列举了几个小白在java中使用方法应该注意的几个地方 1. 方法应该定义在类中2.方法中不可以再嵌套方法3.方法定义的前后顺序无所谓4.想要执行方法必须要调用5.如果方 ...
- 一分钟部署nacos
第一步:下载nacos包 https://github.com/alibaba/nacos/releases D:\testNacos\nacos-server-1.3.0\nacos\bin 最后 ...
- http连接池存在的问题
连接的有效性检测是所有连接池都面临的一个通用问题,大部分HTTP服务器为了控制资源开销,并不会 永久的维护一个长连接,而是一段时间就会关闭该连接.放回连接池的连接,如果在服务器端已经关闭,客 户端是无 ...
- Reface.AppStarter 基本示例
Reface.AppStarter 向应用层提供以下几项 核心 功能 以模块化组织你的应用程序 自动注册组件至 IOC 容器 自动映射配置文件至配置类 在模块定义类中额外追加组件至 IOC 容器 在模 ...
- Qt_IO系统_二进制读写
目录 Qt中的读写 QDataStream QDataStream Qt 是如何存储数据的 如何保证读取数据的正确性? --> 魔术数字,文件版本,Qt版本 魔术数字 文件版本 Qt 版本 读取 ...