【问题标题】:Difference between array<T> and array<T^> where T is ValueTypearray<T> 和 array<T^> 之间的区别,其中 T 是 ValueType
【发布时间】:2016-09-02 23:21:52
【问题描述】:

我正在为我的 C# 项目在本机库上编写 C++/CLI 包装器。我正在尝试将本机 C++ 中的 std::vector 转换为 C# 中的 System.Byte[] 。 在 C++/CLI 中,这两种变体都是有效的

auto arr = gcnew array<System::Byte>(10);
auto arr = gcnew array<System::Byte^>(10);

但在第一种情况下,在 C# 代码中我们得到了 System::Byte[] 类型,而在第二种情况下,我们得到了 System::ValueType[]。

所以我的问题是为什么我们会出现这种奇怪的行为?

【问题讨论】:

  • 不是我的强项,但我相信在第一个示例中,您声明了一个 byte 数组,正如您所期望的那样。第二个示例是声明一个装箱字节数组(一种值类型),以便您可以拥有引用。
  • 愚蠢的我。可能你是对的。我很困惑,因为当您在 C# 中使用 new 关键字创建 System.Byte 时,即没有发生新的 Byte() 装箱。我猜当你调用 gcnew System::Byte() (在 c++/cli 中)适合我上面描述的第二个数组时,会有相同的行为。

标签: c# arrays c++-cli


【解决方案1】:

^ 帽子只能用于引用类型。 Byte 是一种值类型,因此 array&lt;System::Byte&gt; 是正确的声明。

不幸的是,C++/CLI 允许Byte^ 的数组,将值转换为对象是.NET 代码中支持的方案。该数组现在包含对对象的引用,该对象是字节的 boxed 值。装箱转换实现了著名的错觉,即值类型继承自 System::ValueType,而 System::ValueType 派生自 System::Object。在 32 模式下,您现在需要 4 个字节用于对象引用和 12 个字节用于装箱字节对象,而不是一个元素的 1 个字节的存储空间。

好吧,不要那样做。我从来没有遇到过这是必要或有用的场景。有一些场景需要装箱,例如反射,但是直接转到 Object^ 更有意义,因为这是记录此类方法的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-26
    • 2015-11-15
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    相关资源
    最近更新 更多