c# - 排序值类型会创建副本吗?
问题描述
在 C# 中如何实现对值类型的排序?
我无法删除结构的(隐式)默认构造函数以查看编译器/运行时没有调用它,但我怀疑它在排序时会复制,因为即使持有临时(值)进行交换也意味着复制这可以用指针来实现,但是我在泛型代码中看不到任何东西来表明它对值类型和引用类型有什么特别的。
伊利诺伊州
IL_0060: ldloc.0 // fooByValues
IL_0061: ldloc.1 // comparer
IL_0062: callvirt instance void class [System.Collections]System.Collections.Generic.List`1<valuetype DevOpsCourse.Tests.Common.FunctionalComparerTest/FooByValue>::Sort(class [System.Runtime]System.Collections.Generic.IComparer`1<!0/*valuetype DevOpsCourse.Tests.Common.FunctionalComparerTest/FooByValue*/>)
IL_0067: nop
只是指一个我无法查看的虚拟呼叫,所以我不知道它是如何真正实现的。
我也找不到任何与此相关的文档。
解决方案
对于标题中提出的问题,答案是肯定的。
你不会在这里看到任何特别的东西。值类型的变量将值保存在自身内部。任何时候你看到任何形式的赋值给一个值类型的变量,这将是一个副本。
引用类型的变量保存对保存数据的实际对象的引用。当您对引用类型的变量执行赋值时,您会获得该引用的副本,但该引用仍然指向同一个对象。
这就是为什么你不会在这里看到任何特别的东西——这只是对变量的赋值,它们对值类型和引用类型都“做正确的事情”。
(并且引用类型在用作参数时不会通过引用传递。默认情况下,参数传递总是按值传递,但传递的是变量,而不是值)
虽然这可以用指针来实现
请记住,大多数结构无论如何都应该很小。交换指向它们的指针(即使存在这样的指针)很可能比交换值更有效,因为指针很可能比结构大。
例如,一个值类型的数组是一块包含实际值的内存——而不是一块包含指向值的指针的内存。交换两个这样的值的位置的唯一方法是从字面上覆盖它们。
推荐阅读
- swift - 使用 DateFormatter 格式化字符串日期
- python - 如何杀死屏幕上的所有敌人精灵?
- python - Ubuntu 升级到 20.0 后 Python manage.py runserver 抛出错误
- javascript - setTimeout 意外延迟内的控制台日志
- ios - 如何动态调整 UIScrollView 的大小?
- python - 为什么我会收到 +: float 和 str 不支持的错误?
- java - 如何在 Kotlin 回调中做到这一点?
- c++ - 将 shellcode 从文件加载到 char* 在文本末尾出现奇怪的字符
- google-cloud-platform - AI笔记本无法加载
- swift - 在 iOS 14 上向小部件发送结构数组