ref详解(C#)
本质上来说 ref 的就是把 C/C++ 指针的那一套又拿回来了,而且还封装成一套自己的玩法。
我想设计者的初心把 ref 的功能限制得死死的,可能也考虑到 C# 是一门面向业务开发的语言,讲究的是做项目快狠准,性能反而不是第一要素,这个时候的 ref 很简单,看一下代码:
class Program
{static void Main(string[] args){long price = 0;GetPrice(ref price);Console.WriteLine($"output: price={price}");}public static void GetPrice(ref long price){price = 10;} }
// output: price=10
我相信大家都知道,方法参数中ref long price拿的是栈中的地址,对栈地址上的值进行修改,地址上的变量会被修改,和引用类型原理一致,接下来咋就从汇编的角度去看看。
D:\net5\ConsoleApp4\ConsoleApp3\Program.cs @ 16:026b048e 8d4declea ecx,[ebp-14h]026b0491 ff15a0ebc800 call dword ptr ds:[0C8EBA0h] (ConsoleApp3.Program.GetPrice(Int64 ByRef), mdToken:06000002)026b0497 90 nop0:000> bp 026b04910:000> gBreakpoint 1 hitChangeEngineStateeax=00000000 ebx=0057f354 ecx=0057f2d4 edx=783aaa50 esi=02979e7c edi=0057f2dceip=026b0491 esp=0057f2c4 ebp=0057f2e8 iopl=0 nv up ei pl zr na pe nccs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
026b0491 ff15a0ebc800 call dword ptr ds:[0C8EBA0h] ds:002b:00c8eba0=00c2be10
从汇编的lea ecx,[ebp-14h]就能看到,将ebp-14这个单元的内存地址给了 ecx,这个 ecx 也就是作为参数传递给了Price方法,后续的赋值将会影响这个栈位置上的内容。
方法返回值上的 ref
这就有意思了,进入的时候传地址,回来的时候也想传地址,很显然方法线程栈上的 值类型 是传不出去的,毕竟方法返回后,esp,ebp 所控制的方法栈帧空间是要销毁的,所以只能是堆上对象才能实现。
为了方便理解,看如下代码:
class Program
{static void Main(string[] args){ref long price = ref TaskClass.GetCurrentPrice();price = 12;Console.WriteLine($"output: price={price}");}public static ref long GetCurrentPrice(){long[] nums = { 10, 20, 30 };return ref nums[1];}}
// output: price=12
可以看到当前的price=12,同时nums这个数组也被修改了,可以用 windbg 验证一下。
0:000> !dumpheap -type System.Int64[]Address MT Size027ca7b0 04c39d00 36Statistics:MT Count TotalSize Class Name04c39d00 136 System.Int64[]Total 1 objects0:000> dq 027ca7b0 L4027ca7b0 00000003`04c39d00 00000000`0000000a027ca7c0 00000000`0000000c 00000000`0000001e
可以看到上面的000000000000000c被修改成price=12,这时候有人就不爽了,我不希望外面的代码能修改 price 内容,那怎么办呢? 还得在ref后面加上readonly,改造后如下:

到此时写法就有点疯狂了,对 C# 开发者来说很难理解,对熟悉 C/C++ 指针的朋友来说又很不习惯,太纠结了,下面是一段翻译过来的C/C++指针代码。
const long long* getcurrentprice();int main()
{int i = 0;const long long* price = getcurrentprice();price = 12;printf("num=%d, price=%d \n", i, *price);}const long long* getcurrentprice() {long long* num = new long long[3]{ 10,20,30 };return num + 1;
}
对 ref 变量的 in 操作
这又是一套 C/C++ 的玩法,有时候不希望某一个方法对 ref 变量进行修改,注意:是不希望某一个方法进行修改,其他方法是可以的,那这个怎么实现呢?这就需要在入参上加in前缀,把代码修改一下。
class Program
{static void Main(string[] args){ref long price = ref GetCurrentPrice();ModifyPrice(in price);Console.WriteLine($"output: price={price}");}public static ref long GetCurrentPrice(){long[] nums = { 10, 20, 30 };return ref nums[1];}public static void ModifyPrice(in long price){price = 12;Console.WriteLine(price);}
}

可以看到,这时候报错了,如果换成 C++ 就很简单了,只需要在参数上把 in 改成 const 即可。
void modifyprice(const long long* price) {*price = 12;printf("%d", *price);
}

总的来说,ref 这一套玩法太另类了,按实际需求使用,不太会去考虑性能方面的问题。
相关文章:
ref详解(C#)
本质上来说 ref 的就是把 C/C 指针的那一套又拿回来了,而且还封装成一套自己的玩法。 我想设计者的初心把 ref 的功能限制得死死的,可能也考虑到 C# 是一门面向业务开发的语言,讲究的是做项目快狠准,性能反而不是第一要素&#x…...
运维高级-day01
shell回顾 1、快速生成版权控制信息,具体的内容自己替换 [root scripts]# cat ~/.vimrc autocmd BufNewFile *.py,*.cc,*.sh,*.java exec ":call SetTitle()" func SetTitle() if expand("%:e") sh call setline(1,"#!/bin/bash")…...
含分布式电源的配电网可靠性评估matlab程序
微❤关注“电气仔推送”获得资料(专享优惠) 参考文献: 基于仿射最小路法的含分布式电源配电网可靠性分析——熊小萍 主要内容: 通过概率模型和时序模型分别进行建模,实现基于概率模型最小路法的含分布式电源配电网…...
k8s docker总结特殊点
k8s docker总结特殊点 前言一、docker 的驱动。1、cgroup:(Control Groups)2、日志驱动(log driver)3、存储驱动4、网络驱动: 二、k8s中网络插件(常用calico,次flannel)**Flannel:**…...
区块链技术与应用 【全国职业院校技能大赛国赛题目解析】第四套区块链应用后端开发
第四套区块链应用后端开发 环境 : ubuntu20 fisco : 2.8.0 springboot 2.1.1 fisco-java-sdk: 2.7.2 maven 3.8.8 前言 这套后端样题,只涉及调用fisco的系统接口,不涉及此食品溯源项目的业务接口,所以我就直接生成一个springboot项目进行完成此题目。 请提前准备好一…...
《向量数据库指南》——向量数据库Milvus Cloud搭建Excel公式编辑器助手
引言 在日常工作中,Excel是我们经常使用的办公工具,而熟练应用Excel公式对于提高工作效率非常重要。然而,有时候我们会遇到一些复杂的需求,需要用到较为专业的Excel公式,而这正是Excel公式编辑器助手的用武之地。本文将介绍如何利用向量数据库Milvus Cloud搭建GPT大模型和…...
qgis添加arcgis的FeatureServer
左侧浏览器-ArcGIS要素服务器-新建连接 http://sampleserver6.arcgisonline.com/arcgis/rest/services/ 展开-双击即可...
java进阶---多态
多态的概述 什么是多态 同一个对象,在不同时刻表现出来的不同形态 多态的前提 要有继承或实现关系要有方法的重写要有父类引用指向子类对象 多态的具体实现 对象的多态是多态的核心和重点 规则: 一个对象的编译类型与运行类型可以不一致编译类型在定义对象时,就确定了,…...
常用脚本-持续更新(文件重命名、视频抽帧、拆帧、删除冗余文件、yolo2xml、转换图片格式、修改xml)
所有代码位置:Learning-Notebook-Codes/Python/常用脚本 1. 文件重命名 脚本路径:codes/files_rename.py脚本说明:可以自动重命名某个文件夹下指定类型的文件。 修改前文件名称: img1.jpg修改后文件名称: Le0v1n-20231123-X-0001.jpg imp…...
百度文心一言(千帆大模型)聊天API使用指导
开篇不得不吐槽下百度,百度智能云平台首页跳转千帆大模型平台的按钮太多了,不同按钮跳转不同的子页面,不熟悉的,能把人找懵。入口太多,就导致用户不知道从何开始。本文就从一个前端开发人员的角度,教大家快…...
C++知识点总结(7):玩转高精度除法
一、复习高低精度 一个数分为两种类型: 1. 高精度数,即一个长度特别长的数,使用 long long 也无法存储的一类数字。 2. 低精度数,即一个普通的数,可以使用 long long 来存储。 由于高精度除法比较简单,…...
LeetCode算法题解(动态规划,背包问题)|LeetCode1049. 最后一块石头的重量 II、LeetCode494. 目标和
一、LeetCode1049. 最后一块石头的重量 II 题目链接:1049. 最后一块石头的重量 II 题目描述: 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出任意两块石头,然后将…...
使用Pytorch从零开始构建LSTM
长短期记忆(LSTM)网络已被广泛用于解决各种顺序任务。让我们了解这些网络如何工作以及如何实施它们。 就像我们一样,循环神经网络(RNN)也可能很健忘。这种与短期记忆的斗争导致 RNN 在大多数任务中失去有效性。不过&a…...
qRT-PCR相对定量计算详解qPCR相对定量计算方式——2^-(∆∆Ct) deta t
做完转录组分析之后,一般都要求做qRT-PCR来验证二代测序得到的转录本表达是否可靠。荧光定量PCR是一种相对表达定量的方法,他的计算方法有很多,常用的相对定量数据分析方法有双标曲线法,ΔCt法,2^-ΔΔCt法(Livak法)&a…...
BART non-Cartesian 重建:并行成像 压缩感知
本文主要使用并行成像和压缩感知方法实现non-Cartesian MRI 数据的重建。 目录 1 自定义MRI kspace trajectory 2 自定义该 trajectory下的多通道MRI数据 3 使用NUFFT 直接做欠采样数据的重建...
UDP客户端使用connect与UDP服务器使用send函数和recv函数收发数据
服务器代码编译运行 服务器udpconnectToServer.c的代码如下: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include<errno.h> #inclu…...
SLAM ORB-SLAM2(9)闭环检测器
SLAM ORB-SLAM2(9)闭环检测器 1. LoopClosing2. 成员变量2.1. 系统成员变量2.2. 关键帧2.3. 共视关系2.4. 闭环检测2.5. 全局 BA(光束法平差)2.6. 其他操作3. 成员函数3.1. 构造函数3.2. 主要函数3.3. 更新操作3.4. 标识设置和查询接口1. LoopClosing 在《SLAM ORB-SLAM2(…...
目标检测YOLO系列从入门到精通技术详解100篇-【目标检测】SLAM(基础篇)(二)
目录 知识储备 概率论基础 边缘概率 联合概率和独立 独立与条件独立...
TikTok 将开源“云中和”边缘加速器
“从某种意义上说,我们正在努力破解云的骨干网,以造福于我们,”TikTok产品管理基础设施经理Vikram Siwach指出,他解释了该公司即将开源的“全球服务加速器”的好处,这是一个可编程的边缘平台,可将应用程序需…...
【通讯协议】REST API vs GraphQL
在API设计方面,REST和GraphQL各有缺点。下图显示了 REST 和 GraphQL 之间的快速比较。 REST 使用标准 HTTP 方法(如 GET、POST、PUT、DELETE)进行 CRUD 操作。当您需要在单独的服务/应用程序之间提供简单、统一的接口时,效果很好…...
Windows安卓应用安装器:APK Installer使用完全指南
Windows安卓应用安装器:APK Installer使用完全指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 还在为Windows电脑无法安装安卓应用而烦恼吗?…...
Spring Boot Profile 环境管理
Spring Boot Profile 环境管理:多环境配置的艺术 在现代企业级开发中,应用通常需要在不同环境(如开发、测试、生产)中运行,每个环境可能依赖不同的数据库、服务地址或配置参数。Spring Boot 的 Profile 机制为多环境管…...
Diablo Edit2:终极暗黑破坏神II角色编辑器,3大核心功能重塑单机游戏体验
Diablo Edit2:终极暗黑破坏神II角色编辑器,3大核心功能重塑单机游戏体验 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 在暗黑破坏神II的单机冒险中,你是否曾为…...
Wan2.2-I2V-A14B开源镜像实操手册:xFormers加速+FlashAttention-2显存优化
Wan2.2-I2V-A14B开源镜像实操手册:xFormers加速FlashAttention-2显存优化 1. 镜像概述与核心优势 Wan2.2-I2V-A14B是一款专为文生视频任务优化的私有部署镜像,特别针对RTX 4090D 24GB显存配置进行了深度优化。这个镜像最大的特点是内置了xFormers和Fla…...
安卓应用级虚拟定位:FakeLocation Xposed模块的三大革新
安卓应用级虚拟定位:FakeLocation Xposed模块的三大革新 【免费下载链接】FakeLocation Xposed module to mock locations per app. 项目地址: https://gitcode.com/gh_mirrors/fak/FakeLocation FakeLocation是一款基于Xposed框架的开源安卓虚拟定位工具&am…...
终极Gumbo-Parser文档注释指南:Doxygen规范与最佳实践全解析
终极Gumbo-Parser文档注释指南:Doxygen规范与最佳实践全解析 【免费下载链接】gumbo-parser An HTML5 parsing library in pure C99 项目地址: https://gitcode.com/gh_mirrors/gum/gumbo-parser Gumbo-Parser是一个纯C99实现的HTML5解析库,它提供…...
数据库备份恢复方案
数据库备份恢复方案:企业数据安全的生命线 在数字化时代,数据已成为企业的核心资产。数据库作为存储和管理数据的关键系统,其安全性直接影响业务连续性。一次意外的数据丢失或系统崩溃,可能导致巨额经济损失甚至企业信誉受损。一…...
GPT-5架构泄露?Kubernetes 1.31发布与Rust重构浪潮下的云原生之变
🔥个人主页:北极的代码(欢迎来访) 🎬作者简介:java后端学习者 ❄️个人专栏:苍穹外卖日记,SSM框架深入,JavaWeb ✨命运的结局尽可永在,不屈的挑战却不可须臾或…...
告别手动标注!用MedCLIP-SAM+BiomedCLIP实现医学图像的文本描述自动分割(附代码实战)
医学图像智能分割实战:基于MedCLIP-SAM的零样本标注解决方案 医学影像分析领域长期面临一个核心痛点:高质量标注数据的获取成本极高。一张胸部X光片中肺结节的精确轮廓标注,可能需要资深放射科医生花费数十分钟反复勾勒。这种人工标注的瓶颈严…...
全志T113-i开发板G2D硬件加速实战:YUV转RGB性能优化与工业级应用解析
1. 全志T113-i开发板与G2D硬件加速初探 第一次拿到全志T113-i开发板时,我就被它37mm39mm的迷你尺寸惊艳到了。这块工业级核心板能在-40℃~85℃环境下稳定运行,搭载双核Cortex-A71.2GHz处理器和RISC-V协处理器,最吸引我的是它内置的G2D 2D图形…...
