【问题标题】:What's the difference between a non-unmanaged type and a managed type?非托管类型和托管类型有什么区别?
【发布时间】:2012-04-14 00:59:00
【问题描述】:

当我出于实验目的编写以下 sn-p 时,它引发了悬停错误(见截图):

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

sn-p:

dynamic* pointerToDynamic = &fields;

虽然代码显然是不允许的(您不能获取托管类型的地址),但它向我提出了一个问题:非托管类型是什么以及它与托管类型?还是只是 Visual Studio 试图搞笑?

【问题讨论】:

  • 显然非非托管类型是非非非非托管类型。嗯。
  • 不要过多解读笨拙的错误信息。 C# binder 根本不支持指针。
  • 没有区别。措辞仅仅是由于预期的行为。 “指针用于非托管类型。这不是其中之一。它是非托管类型。”错误不是字段是托管的,而是字段不是非托管的,即使这两个短语的意思相同。
  • 请记住:如果一个程序想要被告知向左走,而您告诉它向右走,它可能会给您一个非向左错误。
  • @JustinTime,有趣的一点,但这里的类比是,“如果程序告诉你不向左走,而你向左走,它会给你一个不-不左错误”;))))

标签: c# .net types unmanaged managed


【解决方案1】:

非托管指针和非托管指针是有区别的。

托管指针是托管堆上对象的句柄,AFAIK 仅在托管 C++ 中可用。它相当于 C# reference 到一个对象。另一方面,非托管指针等价于传统的 C 风格指针,即内存位置的地址; C#为此提供了一元&运算符、fixed关键字和unsafe上下文。

您试图获取指向托管字段的指针(dynamic 实际上是 System.Object 是伪装),而 C# 只允许指向非托管对象的指针,因此措辞:您的类型是非托管的。

关于here 的更多信息。

更新: 更清楚地说,托管 C++ 支持经典 C 样式的指针和引用。但是为了保持 C++ 术语的一致性,它们被分别称为 unmanaged 和 managed pointers。 C# 还支持指针(在unsafe 上下文中显式)和引用(在涉及引用类型的对象时隐式地),但后者不称为“托管指针”,它们只是引用。

总结一下:在 C++ 中有非托管和托管指针,在 C# 中 - 非托管指针和引用。

希望现在有意义。

【讨论】:

  • 鉴于错误,这更有意义。我从来没有意识到非托管和非托管是不同的东西(看起来你只需要解释托管/非托管指针之间的区别,错字?)。但考虑到你的最后一段,这似乎是一个合理的解释。
  • @Abel:我更新了我的答案,如果不清楚,抱歉。也许现在好一点了。
  • 恐怕你重复了你已经说过的话;)。在您的第一行中,您提到了 un 托管和 non- 托管指针之间的区别。后者不再在您的文本中提及。我知道(非)托管指针之间的区别。
  • @Abel:哦,现在我明白了,谢谢。这句话确实具有误导性。
【解决方案2】:

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

那么非托管类型真正的意思是托管类型。

这里的问题是托管类型因为位于堆上,所以您无法获得指向的指针。您可以使用 fixed 关键字获取指针,但这主要用于数组。

【讨论】:

  • 是的,我知道,谢谢。我真正好奇的是这里的措辞。为什么 IntelliSense 将其称为非托管类型,而它意味着托管类型?在所有其他相关错误中,它被简单地称为托管类型。真的没有区别吗?语义上:清洁、不清洁和非不清洁都是不同的。非托管?
猜你喜欢
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 2011-03-23
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
  • 1970-01-01
相关资源
最近更新 更多