值和引用类型混淆

2023-11-30

我在每个关于这个主题的网站上都读过,并且在过去几天里阅读了 Jon Skeets 的文章参考文献和值 and 参数传递。我了解这两种类型的概念,它们代表什么以及值和参考参数的区别是什么是另一个规范。

我了解它的工作原理以及如何使用它,但我不明白每个人都在谈论这个主题。你们都说,例如int是一个值类型并且string是一个引用类型。但根据我的理解,类型基本上只取决于声明它们的类的类型。

看一下这段代码片段就可以理解我的意思:

public struct IntHolder
{
   public int number;
}

IntHolder first = new IntHolder();
first.number = 5;
IntHolder second = first;
first.number = 6;

Now second.number值为 5。如果您更改struct to class, number将充当引用类型,所以这根本不重要int一般来说是一个值类型,它只是关于类的类型。同样的例子适用于string, ETC... 。

显然,声明对象的类的类型设置了其对象的类型,否则我误解了一个核心概念。请纠正我并帮助我正确理解它,或者告诉我这句话背后的含义是什么int string等等...有一个特殊的类型,尽管它们何时初始化并不重要,所以基本上总是如此。


这与您要更改的字段的类型无关。这里相关的实际上只是父类型的类型:

IntHolder first = new IntHolder();
IntHolder second = first;

取决于种类IntHolder这有两种不同的效果:

对于值类型 (struct),这会创建一个copy。值类型对象的数据存活with对象,因此所有内容都被复制。这有点相当于:

IntHolder second = new IntHolder();
second.number = first.number;
// and all other fields (visible or not) are copied too

这意味着对某个字段的赋值copied值类型将覆盖该值而不影响原始对象。这就像局部变量的行为方式:

var x = 5;
var y = 2;
y = 3; // this does not change x

但是,当类型是引用类型时,赋值second = first只是复制参考资料。两者保存值的底层对象是相同的。因此,对任何一个对象的更改都会影响另一个对象,因为没有“other”:它是同一个对象,只是被两个单独的变量引用。


回答评论中的后续问题:

我该如何想象int变量是值类型并且string是引用类型吗?我的意思是,所以int变量直接包含数字和string变量就像一个指向字符串对象存储位置的指针?

是的,就是这样。引用的值基本上只是指向对象实际所在内存的指针,而值类型的值是整个对象本身。

这就是为什么例如将值类型作为方法的参数意味着当调用该方法时,整个值类型对象将被复制到堆栈中以供该方法执行。

类型是值类型并不意味着它的成员也都是值类型。例如,值类型中字符串成员的实际存储值仍然是对字符串对象的引用。类似地,引用类型的实际内存将包含值类型的实际值以及对other引用类型的内存位置。

如果父类型总是比对象类型更重要,那么我可以使用 int 和 string 类型做什么?

没有什么比另一个更重要的了。作为值或引用类型的对象仅影响该对象的存储方式。对于对象的成员,这是完全单独评估的。

例如,如果您只有一个类和一堆变量,是否可以将其中一些变量设置为对另一个变量的引用int变量。

你不能像在 C 中那样拥有值类型的引用指针,不。但是您可以引用字段,从而允许您更改值类型字段的值。例如:

class Test
{
    private int field;

    public void ShowExample()
    {
        // set the value
        field = 12;

        // call the method and pass *a reference* to the field
        // note the special syntax
        MutateField(ref field);

        // the field, which is a value type, was mutated because it was passed as a reference
        Console.WriteLine(field == 4);
    }

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

值和引用类型混淆 的相关文章

  • 将复选框添加到 UniformGrid

    我正在尝试将复选框动态添加到 wpf 中的统一网格中 但看起来网格没有为它们分配足够的空间 所以它们都有点互相重叠 这就是我将它们添加到后面的代码中的方法 foreach string folder in subfolders PathCh
  • 无法使用已与其底层 RCW 分离的 COM 对象。在 oledb 中

    我收到此错误 但我不知道我做错了什么 下面的代码在backrgroundworker中 将异常详细信息复制到剪贴板 System Runtime InteropServices InvalidComObjectException 未处理 通
  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • 如何避免情绪低落?

    我有一个实现状态模式每个状态处理从事件队列获取的事件 根据State因此类有一个纯虚方法void handleEvent const Event 事件继承基础Event类 但每个事件都包含其可以是不同类型的数据 例如 int string
  • 如何忽略“有符号和无符号整数表达式之间的比较”?

    谁能告诉我必须使用哪个标志才能使 gcc 忽略 有符号和无符号整数表达式之间的比较 警告消息 gcc Wno sign compare 但你确实应该修复它警告你的比较
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • 将自定义元数据添加到 jpeg 文件

    我正在开发一个图像处理项目 C 我需要在处理完成后将自定义元数据写入 jpeg 文件 我怎样才能做到这一点 有没有可用的图书馆可以做到这一点 如果您正在谈论 EXIF 元数据 您可能需要查看exiv2 http www exiv2 org
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • Bootstrap .popover('show')、.popover('hide') 不起作用。将其绑定到点击作品

    我有一个已绑定到弹出框的按钮 当有人单击弹出窗口中的表情符号之一时 我想隐藏弹出窗口 然而 smiley popover hide 不起作用 不幸的是 我无法用准系统代码重现这一点 它只发生在实时站点上 即https coinchat or
  • 作为不同用户的 RPM %post

    我需要在 RPM 的 post 部分中以不同用户身份运行命令 目前我正在通过 python 使用一些 hack 但这不是最好的方法 它确实感觉有点脏 post p usr bin python import os pwd subproces
  • 将一个向量中的每个元素与第二个向量中的每个元素相加

    我想将一个向量中的每个元素与另一个向量中的每个元素相加 如下所示 but避免 for 循环 有没有简单的方法呢 vadd lt function vrow vcol vmatrix lt matrix nrow length vrow nc
  • 静态内容不能引用非静态方法

    我无法编译以下代码 public class Test public static void main String args int a calcArea 7 12 System out println a int calcArea in
  • 如何使用斯坦福解析器将文本拆分为句子?

    如何使用将文本或段落拆分为句子斯坦福解析器 有没有什么方法可以提取句子 比如getSentencesFromString 因为它是规定的Ruby 您可以检查 DocumentPreprocessor 类 下面是一个简短的片段 我认为可能还有
  • 遇到 0 时按组重置的 Cumsum

    下面是我的数据框 我想得到 是 列 我似乎无法理解cumsum当它根据 id 的 值 字段达到 0 时重置 还有其他类似的问题 但解决方案不适用于我的实际数据集 test lt data frame id c 1 1 1 1 2 2 2 2
  • 如何在具有2000万行数据集的MySQL中删除重复项?

    我有一个很大的 MySQL 数据库 我需要快速删除重复的项目 它看起来是这样的 id text1 text2 1 23 43 2 23 44 3 23 44 删除后 表的剩余部分应为 id text1 text2 1 23 43 3 23
  • 将数组存储在共享首选项中

    我有一个Array具有整数值 它会随着时间的推移而增长 它大约有最多 50 个值 我想将数组持久存储 因此我考虑将其存储在SharedPreferences 我知道其中不能存储复杂类型 但我也听说要序列化Array然后将其存储在Shared
  • 如何在使用 Electron-builder 构建 exe 后运行“sqlite3”

    我在以下人员的帮助下构建了我的电子应用程序https medium com jspoint packaging and distributing electron applications using electron builder 31
  • DOMPDF 中的自定义宽度和高度

    无论如何 我可以设置生成的 PDF 的宽度和高度吗 我想自定义PDF的宽度和高度 通常它会采用短铜版纸的尺寸 但我如何定制它 举例来说 我希望它的大小为 200 x 500 像素 任何想法将不胜感激 干杯 您可以通过在调用 DOMPDF s
  • Magento - 列出产品类别

    在 Magento 的每个产品详细信息页面上 我想列出属于哪些类别 我将如何实现这一目标 尝试一下 currentCatIds product gt getCategoryIds and also categoryCollection Ma
  • 在 primefaces 中绑定文件下载参数

    我想在 primefaces 中下载一个名称可能不同的文件 这是控制器的代码 ManagedBean name fileDownloadController eager true ViewScoped public class FileDo
  • 如何在不刷新整个页面的情况下重新加载DIV内容

    我只想用我得到的内容替换 DIV 内容 当我使用ajax向服务器发出get请求后 ajax type GET url http 127 0 0 1 8000 result age ageData occasion occasionData
  • 如何在仅支持常量表达式的函数中使用变量作为参数

    我正在使用这个功能 delay cycles var 我收到以下错误 论证到 delay cycles必须是常量表达式 很公平 但我怎样才能绕过这个呢 我每次都必须以不同的值延迟我的程序 我从 RS232 接收数据并将其存储在一个int多变
  • Python lambda函数下划线冒号语法解释?

    在以下 Python 脚本中 其中 aDict 是字典 0 在 lambda 函数中起什么作用 sorted aDict items key lambda 0 让我们把它分开 1 假设你有一个字典 di di one 1 two 2 thr
  • 如何判断会话是否处于活动状态? [复制]

    这个问题在这里已经有答案了 根据请求 您可以通过几种不同的方式来判断会话是否已启动 例如 isSessionActive session id Or isSessionActive defined SID 然而 如果您启动一个会话然后关闭它
  • Xamarin WKWebView 和 Cookie

    我有一个 Xamarin Forms 应用程序 它使用 cookie 来跟踪登录状态并同时使用 HTTPRequest 和 Webview 因此两者都需要共享 cookie 对于 UIWebView 这些 cookie 是共享的 无需我进行
  • cpuid命令显示信息的问题

    的信息llc缓存显示使用cpuid command在Linux上是 cache 3 cache type unified cache 3 cache level 0x3 3 self initializing cache level tru
  • Android NDK 中缺少 std::wstring 支持的解决方案?

    我有一个游戏 它在数千个地方使用 std wstring 作为其基本字符串类型 并使用 wchar t 及其函数进行操作 wcsicmp wcslen vsprintf 等 问题是 R5c 撰写本文时的最新 ndk 不支持 wstring
  • 值和引用类型混淆

    我在每个关于这个主题的网站上都读过 并且在过去几天里阅读了 Jon Skeets 的文章参考文献和值 and 参数传递 我了解这两种类型的概念 它们代表什么以及值和参考参数的区别是什么是另一个规范 我了解它的工作原理以及如何使用它 但我不明