gpt4 book ai didi

c# - 为什么C#不像C++/CLI那样直接在托管堆中修改字段?

转载 作者:行者123 更新时间:2023-11-30 23:10:17 24 4
gpt4 key购买 nike

正如我在 Jeffrey Richter 所著的C# via CLR 一书中看到的,在谈到装箱和拆箱/复制操作时,Richter 先生展示了一个演示:

public static void Main() {
Point p; // Point is a value type defined before
p.x = p.y = 1;
Object o = p; // Boxes p; o refers to the boxed instance

// Change Point's x field to 2
p = (Point) o; // Unboxes o AND copies fields from boxed
// instance to stack variable
p.x = 2; // Changes the state of the stack variable
o = p; // Boxes p; o refers to a new boxed instance
}

为了改变装箱实例的值,我们需要先拆箱再装箱,性能不是很好。

为了避免我对这本书的误解,下面是作者的原话:

However, in some languages like C++/CLI, they allow you to unbox a boxed value type without copying the fields.Unboxing returns the address of the unboxed portion of a boxed object (ignoring the object’s type object pointer and sync block index overhead). You can now use this pointer to manipulate the unboxed instance’s fields (which happen to be in a boxed object on the heap). For example, the previous code would be much more efficient if written in C++/CLI, because you could change the value of Point’s x field within the already boxed Point instance. This would avoid both allocating a new object on the heap and copying all of the fields twice!

我的问题来了:为什么 C# 不做 C++/CLR 做的事情?是否还有其他一些重要问题阻止 C# 团队进行这种“冗余”设计并使性能不如我们预期的那样好?这种“不自然”行为的背后是什么?

最佳答案

C# 和 C++ 的哲学有些不同。与作为系统编程语言的 C++ 不同,C# 想要使程序员免于处理内存分配和指针,因此它试图隐藏内存管理中涉及的一些细节。在 C# 中,值类型等同于 C++ 中的基本类型和结构。它们只是内存中某处的字节序列。在 C++ 中,您可以轻松地声明一个指向 int 或 struct 的指针,无论它位于何处,但 C# 不允许这样做。这种间接隐藏在装箱/拆箱机制中。

“装箱”大致意思是在堆上创建值类型,并静默返回对这 block 内存的对象引用。拆箱只是颠倒了这种间接性。每当您在需要引用类型的上下文中使用值类型时,装箱/拆箱就会自动发生 - 例如,将整数转换为对象时:

Int32 i4Value = 12345;
Object pValue = (Object) i4Value;

将对象引用转换回整数会自动取消对值的装箱,即将其从堆中复制为正常值。

C++/CLI 团队做了很多魔术来让 C++ 程序员使用低级 C# 功能。这是一个例子。它们利用 C++ 语法让您做一些 C# 程序员甚至不知道的事情,因为它们发生在幕后的某个地方。

坦率地说,尽管我整天都在编写 C++/CLI 代码,但我从来不需要使用 C++/CLI 的这种特殊的装箱/拆箱技巧。但是,在某些情况下肯定没有其他方法 - 例如,当连接一些无法更改的奇怪的第 3 方 C# 组件时,因为没有可用的源代码。

关于c# - 为什么C#不像C++/CLI那样直接在托管堆中修改字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45433906/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com