引用传递的参数类型,加不加ref是不同的

2023-10-27

 教科书上说引用传递的参数引用时,加不加ref都可以,都会改变参数原来的值,值传递参数引用时如果想要改变原来的值,必须加ref。以前遇到的大部分情况确实是如此,引用传递类型比如ArrayList,DataTable到另一个方法中,并在该方法中改变参数值,原调用方法处的变量确实改变了。但是今天遇到一个问题,引用的DataTable如果不加ref关键字,调用方法改变其值后却不变,而加上ref关键字后改值却变了,示例代码如下: 

private void button1_Click(object sender, System.EventArgs e)
  {
   DataTable dt = new DataTable();
   changearray( dt);   调用方法改变其值后,dt仍然没有数据
  
  }  

private void changearray( DataTable dtRef)
  {
   DataTable dtlist = new DataTable();
   dtlist.Columns.Add("A",typeof(string));
   DataRow dr = dtlist.NewRow();
   dr["A"] = "9999999999";
   dtlist.Rows.Add(dr);
   dtRef = dtlist.Copy();
              
  }

加上ref关键字后:

private void button1_Click(object sender, System.EventArgs e)
  {
   DataTable dt = new DataTable();
   changearray( ref dt);   调用方法改变其值后,dt中有数据了  
  }  

private void changearray( ref DataTable dtRef)
  {
   
   dtlist.Columns.Add("A",typeof(string));
   DataRow dr = dtlist.NewRow();
   dr["A"] = "9999999999";
   dtlist.Rows.Add(dr);
   dtRef = dtlist.Copy();
  }

更奇怪的是,如下调用方法,无论加不加ref都是可以改变值的:

private void button1_Click(object sender, System.EventArgs e)
  {
   DataTable dt = new DataTable();
   changearray( dt);
  
  }

  private void changearray( DataTable dtRef)
  {   
   dtRef.Columns.Add("A",typeof(string));
   DataRow dr = dtRef.NewRow();
   dr["A"] = "9999999999";
   dtRef.Rows.Add(dr);        
  }

       百思不得其解,查了很多资料,基本上都是认为引用传递类型加不加ref都是一样的,可以目前发现的问题是明明不一样。后来网上搜到了遇到同一问题的帖子,虽然没有对该现象权威的解释,但是基本明白了出现问题的根源。

      传递引用 和传递 ref 引用的区别,是第一个传递指针,第二个是传递指向指针的指针,所以第一个可以修改那个指针指向的内容,但不能修改指针本身的地址,第二个则可以修改指针地址

传递引用 和传递 ref 引用的区别,学过C++的话应该很好理解.
就是指针(*)和引用(&)的区别.
void mothod(DataTable dt) 传递的是dt变量所指向的内存空间
void mothod(ref DataTable dt) 传递的是dt变量本身的内存地址

这里可能是作用域的问题
在changearray方法里面如果不使用dt=new DataTable()语句,则在changearray中处理dt,button1_Click里的dt都会变化,
因为button1_Click()里的dt和changearray里的dt是DataTable类的同一个实例,只是在changearray中改变了它的值,作用域在button1_Click()中没有发生变化。
如果在changearray中有dt=new DataTable()语句,相当于重新定义DataTable类的新实例,此dt已非彼dt,
dt的作用域此时只在changearray中有效,也就是说changearray中的dt根本和button1_Click里面的dt已不是同一个实例,在changearray里面根本就没有对button1_Click()里面的dt做任何改变。

所以可以预见的语句:dtRef = dtlist.Copy();对dtRef 进行了重新初始化处理,所以如果不加ref时,dtRef就被重新定义了,dtRef所指向的地址与原dt不同了。如果加上ref引用时,因为传递的变量所在的地址,dtRef虽然重新定义了,不管其变量地址指向哪里,因为传递了dt的所在地址,其值仍然是可以得到的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

引用传递的参数类型,加不加ref是不同的 的相关文章

  • 为什么我不能用 `= delete;` 声明纯虚函数?

    Intro 纯虚函数使用通用语法声明 virtual f 0 然而 自 c 11 以来 有一种方法可以显式地传达non existence 特殊 成员函数的 Mystruct delete eg default constructor Q
  • 如何在 Android NDK 中创建新的 NativeWindow 而无需 Android 操作系统源代码?

    我想编译一个 Android OpenGL 控制台应用程序 您可以直接从控制台启动 Android x86 运行 或者从 Android x86 GUI 内的 Android 终端应用程序运行 这个帖子 如何在 Android NDK 中创
  • 显示异常时的自定义错误消息:从客户端检测到潜在危险的 Request.Form 值

    我在我的 Web 应用程序中使用 ASP NET 的登录控件 当发生此异常时 我想在标签上显示一种有趣的错误类型System Web HttpRequestValidationException A potentially dangerou
  • JSON 数组到 C# 列表

    如何将这个简单的 JSON 字符串反序列化为 C 中的列表 on4ThnU7 n71YZYVKD CVfSpM2W 10kQotV 这样 List
  • POCO HTTPSClientSession 发送请求时遇到问题 - 证书验证失败

    我正在尝试使用 POCO 库编写一个向服务器发出 HTTPS 请求的程序 出于测试目的 我正在连接到具有自签名证书的服务器 并且我希望允许客户端进行连接 为了允许这种情况发生 我尝试安装InvalidCertificateHandler这是
  • 暂停下载线程

    我正在用 C 编写一个非常简单的批量下载程序 该程序读取要下载的 URL 的 txt 文件 我已经设置了一个全局线程和委托来更新 GUI 按下 开始 按钮即可创建并启动该线程 我想要做的是有一个 暂停 按钮 使我能够暂停下载 直到点击 恢复
  • ASP MVC:服务应该返回 IQueryable 的吗?

    你怎么认为 你的 DAO 应该返回一个 IQueryable 以便在你的控制器中使用它吗 不 您的控制器根本不应该处理任何复杂的逻辑 保持苗条身材 模型 而不是 DAO 应该将控制器返回给视图所需的所有内容 我认为在控制器类中看到查询 甚至
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • 如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用?

    首先 一些背景信息 我尝试以 Herb Sutter 在他的解决方案中介绍的方式使用 Pimpl 习语 得到了 101 http herbsutter com gotw 101 这在头文件中看起来像这样 include pimpl h h
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 如何挤出平面 2D 网格并赋予其深度

    我有一组共面 连接的三角形 即二维网格 现在我需要将其在 z 轴上挤出几个单位 网格由一组顶点定义 渲染器通过与三角形数组匹配来理解这些顶点 网格示例 顶点 0 0 0 10 0 0 10 10 0 0 10 0 所以这里我们有一个二维正方
  • 尚未处理时调用 Form 的 Invoke 时出现 ObjectDisposeException

    我们得到一个ObjectDisposedException从一个电话到Invoke在尚未处理的表格上 这是一些演示该问题的示例代码 public partial class Form2 Form void Form2 Load object
  • 是否可以有一个 out ParameterExpression?

    我想定义一个 Lambda 表达式out范围 有可能做到吗 下面是我尝试过的 C Net 4 0 控制台应用程序的代码片段 正如您在 procedure25 中看到的 我可以使用 lambda 表达式来定义具有输出参数的委托 但是 当我想使
  • Android 自定义警报对话框中的 OnClickListener

    我是一个自学成才的初学者 感谢耐心 谢谢 在 Eclipse 中 我使用自己的 xml 文件 custom dialog 创建了一个自定义警报对话框 称为 usernamealert 如果用户尚未输入用户名 即 username lengt
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触
  • 使用 CSharpCodeProvider 类编译 C# 7.3 的 C# 编译器版本是什么?

    我想使用 Microsoft CSharp CSharpCodeProvider 类来编译 C 7 3 代码 编译器版本在 IDictionary 中指定 在创建新的 CSharpCodeProvider 时将其作为输入 例如 Compil
  • 用于 C# XNA 的 Javascript(或类似)游戏脚本

    最近我准备用 XNA C 开发另一个游戏 上次我在 XNA C 中开发游戏时 遇到了必须向游戏中添加地图和可自定义数据的问题 每次我想添加新内容或更改游戏角色的某些值或其他内容时 我都必须重建整个游戏或其他内容 这可能需要相当长的时间 有没
  • Googletest:如何异步运行测试?

    考虑到一个包含数千个测试的大型项目 其中一些测试需要几分钟才能完成 如果按顺序执行 整套测试需要一个多小时才能完成 通过并行执行测试可以减少测试时间 据我所知 没有办法直接从 googletest mock 做到这一点 就像 async选项
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop
  • 匿名结构体作为返回类型

    下面的代码编译得很好VC 19 00 23506 http rextester com GMUP11493 标志 Wall WX Za 与VC 19 10 25109 0 标志 Wall WX Za permissive 这可以在以下位置检

随机推荐

  • Appium连接手机时报权限错误 requires:android.permission.WRITE_SECURE_SETTINGS

    报错信息 java lang SecurityException Permission denial writing to settings requires android permission WRITE SECURE SETTINGS
  • ubuntu server 22.04 静态ip设置

    ubuntu server 22 04 静态ip设置 我一般配置ip都是在系统安装完成后才进行设置 查看当前网络 需要了解的是 你该静态ip是该的哪个网卡的别搞错了 ifconfig ip a 这两个命令 都是可以的 修改配置文件 etc
  • C# 读写西门子PLC数据,包含S7协议和Fetch/Write协议,s7支持200smart,300PLC,1200PLC,1500PLC...

    本文将使用一个gitHub开源的组件技术来读写西门子plc数据 使用的是基于以太网的TCP IP实现 不需要额外的组件 读取操作只要放到后台线程就不会卡死线程 本组件支持超级方便的高性能读写操作 官方地址 http www hslcommu
  • 关于java.servlet.*缺失问题

    上图使用的tomcat版本为10 0 23 此问题目前出现在Tomcat10系列 而 Javax servlet 标红 不存在 的原因是因为包名改了 Tomcat 10 用以下的 import import jakarta servlet
  • ESP12f/E(8266)以及STM32串口自动烧录电路

    在使用CH340C芯片进行自动烧录时 经常会用到RTS和DTR两个联络输出信号 电脑烧录程序控制芯片这两个引脚的高低电平 从而控制主控芯片IO0和reset引脚进行自动烧录并复位 这两个信号都是低电平有效 STM32 这里需要注意的是使用的
  • jpa报错:check the manual that corresponds to your MySQL server version for the right

    原因一 check the manual that corresponds to your MySQL server version for the right 因为表字段中使用了关键字 private String describe 解决
  • 查看tensor的形状,行列大小

    torch size是tuple 元组的子类 因此他支持元组所有的操作 如x size 0 import pandas as pd import numpy as np import torch x torch rand 5 3 print
  • 基于内容的课程推荐系统

    引言 基于Coursera课程数据集 将课程名称向量化 计算与目标课程标题向量最相似的课程向量 实现基于内容的课程推荐 代码实现 准备实验环境与数据 import numpy as np import pandas as pd from s
  • SHELL学习笔记----IF条件判断,判断条件

    前言 无论什么编程语言都离不开条件判断 SHELL也不例外 if list then do something here elif list then do another thing here else do something else
  • docker容器服务无法访问题解决

    问题现象 前不久通过docker启动的容器服务均无法访问 开始以为容器坏了 也不着急使用就没当回事 最近这几天需要部署监控服务 容器启动后浏览器访问一直提示网络连接错误 并且在启动容器时有以下提示 WARNING IPv4 forwardi
  • Java基础--- 抽象方法和类 Abstract Methods and Class

    Java基础 抽象方法和类 Abstract Methods and Class 抽象方法 Abstract Method 抽象类 Abstract Class 关于抽象类不能被实列化 使用new operator 抽象方法 Abstrac
  • 计算机是学前端开发好还是后端开发好?

    学前端还是学后端 这是个好问题 很多人问 在我看来 它可能是个伪命题 既然题主问的是前后端 那我默认你问的是网站开发的问题 这是我们很长一段时间里对于网站开发工程师的分工 那么我们来看传统意义上 前后端是如何分工的 后端工程师负责渲染出基础
  • sql server 存储过程中输入参数需要用in而失效的问题解决方案

    在存储过程中使用IN函数 传入多个参数时 会有问题 因为输入参数 1 2 3 是一个数据 而不是一个集合 导致sql失效 三种解决方案 1 建立函数分割输入参数里面的 create FUNCTION dbo Split2 RowData v
  • mac下编译protobuf c++

    由于protobuf官网的文档是英文版的 并且并没有比较详细的说明 可能说得很清楚了 只是我这种英文渣看不懂 学习起来着实费了一翻功夫 在此 记录一下学习过程 希望尽量详细 一 编译过程需要的工具 1 protobuf源码 下载地址 htt
  • 【HTML+CSS】之CSS布局

    常用布局方式 table 表格布局 float 浮动 margin inline block 布局 flexbox布局 1 flexbox 布局
  • WebDav的几种应用方法

    windows系统将阿里云盘挂载成本地磁盘使用 1 获取阿里云盘的登录token 2 使用脚本程序运行起来webdav aliyundriver的jar包 3 使用RaiDrive软件将阿里云盘挂载成本地磁盘 4 需要注意的是 token的
  • 分布式存储Ceph中的逻辑结构Pool和PG

    Ceph中的逻辑对象有Object Pool PG 本文简单介绍相关的概念以及之间的关系 PG状态变化过程等 1 Ceph集群中的逻辑结构 1 1 Object Object是Ceph的最小存储单元 大小可以自己定义通常为2M或4M 每个O
  • 某网站登录接口password参数还原

    本次分析的网站 aHR0cHM6Ly9tLmN0eXVuLmNuL3dhcC9tYWluL2F1dGgvbG9naW4 cmVkaXJlY3Q9JTJGbXk 1 抓包 本次需要分析的是 password 参数 所以 在控制台全局搜索 pa
  • 12000+套Midjourney描述词!有了它真的可以为所欲为!

    今天给各位来个猛的 更新一些最新最全的Midjourney关键词 方便大家在AI绘画中使用 有了这些关键词你可直接复制粘贴拿过来稍加修改就可以用了 当然这些关键词不仅仅只适合Midjourney这个平台 其他AI类绘画工具同样适用 Midj
  • 引用传递的参数类型,加不加ref是不同的

    教科书上说引用传递的参数引用时 加不加ref都可以 都会改变参数原来的值 值传递参数引用时如果想要改变原来的值 必须加ref 以前遇到的大部分情况确实是如此 引用传递类型比如ArrayList DataTable到另一个方法中 并在该方法中