一个非非托管类型和一个托管类型有什么区别?

16

当我写下以下代码段用于实验目的时,它引发了悬停错误(见截图):

无法声明指向非托管类型“dynamic”的指针

代码段:

dynamic* pointerToDynamic = &fields;

虽然这段代码明显是不允许的(你不能取得托管类型的地址),但它引发了一个问题:什么是非非托管类型,它与托管类型有何不同?或者这只是Visual Studio想要逗我们笑吗?

enter image description here


7
显然,非无管理类型是一个非非非无管理类型。嗯。 - Kent Boogaart
3
不要对笨拙的错误信息过分解读。C#绑定器不支持指针。 - Hans Passant
3
没有什么区别,措辞只是因为期望的行为不同而已。“指针是用于非托管类型的。这不是那种类型。它是一种非非托管类型。” 错误不在于 fields 是托管的,而在于 fields 不是非托管的,尽管这两个短语意思相同。 - Michael Edenfield
只需记住:如果程序想要被告知向左走,而你告诉它向右走,它可能会给你一个非左错误。 - Justin Time - Reinstate Monica
1
@JustinTime,很有趣的观点,但这里的类比是,“如果程序告诉你不要向左走,而你向左走了,它会给你一个未非左错误” ;)))) - Abel
2个回答

8

非托管指针和未管理指针是不同的。

受控制的 指针 是一个到托管堆上对象的句柄,在托管 C++ 中可用。它相当于 C# 对象的 引用。另一方面,未管理指针相当于传统的 C 风格指针,即内存位置的地址;C# 提供了一元 & 运算符、fixed 关键字和 unsafe 上下文来实现它。

您正在尝试获取到托管字段的指针(dynamic 实际上是伪装成的 System.Object),而 C# 只允许指向非托管对象的指针,因此使用“non-unmanaged”这样的词语。

更多相关信息请参考这里

更新:为了更加清晰,托管 C++ 支持经典的 C 风格 指针引用。但是为了保持 C++ 术语的一致性,它们分别被称为 未管理托管 指针。C# 也支持指针(在 unsafe 上下文中明确支持)和引用(每当参与引用类型对象时隐式支持),但后者称为“托管指针”,它们只是引用。

总之:在 C++ 中有未管理和托管指针,在 C# 中有未管理指针和引用。

希望现在能更加清楚。


考虑到错误,这更有意义。我从未意识到非托管和不受管理的是不同的东西(而且似乎你只解释了托管/非托管指针之间的区别,打字错误?)。但考虑到你的最后一段,这似乎是一个合理的解释。 - Abel
@Abel:我更新了我的回答,如果不够清晰请谅解。现在或许好一些了。 - Igor Korkhov
很抱歉,你重复了之前说过的内容 ;)。在你的第一行中,你提到了托管和托管指针之间的区别。然而后者在你的文本中没有再次提到。我知道(非)托管指针之间的区别。 - Abel
@Abel:哦,现在我明白了,谢谢。这个短语确实有误导性。 - Igor Korkhov

2

您无法创建指向托管类型的指针。虽然int、double等是托管类型,但它们有非托管对应项。

因此,“非非托管类型”实际上是指“托管类型”。

问题在于,由于托管类型位于堆上,您无法获取指向其的指针。您可以使用fixed关键字获取指针,但这主要用于数组。


是的,我知道这一点,谢谢。我真正好奇的是这里的措辞。为什么IntelliSense称其为非非托管类型,而它实际上是托管类型?在所有其他相关错误中,它只被称为托管类型。难道真的没有区别吗?从语义上讲:干净、不干净和非不干净都是不同的。非非托管? - Abel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接