1

当我声明嵌套值类型的句柄时,Visual Studio(2008 和 2010)给我以下编译器错误:

error C2248: 'Outer::Inner' : cannot access private struct declared in class 'Outer'

下面是编译失败的代码:

ref class Outer
{
private:
    value struct Inner { };

void F()
{
    Inner i; // OK
    Inner^ h; // C2248
}
};

当我将Inner的类型从value struct更改为ref struct时,问题就消失了。

ref class Outer
{
private:
    ref struct Inner { };

void F()
{
    Inner i; // OK
    Inner^ h; // OK
}
};

是否有关于我错过的嵌套值类型句柄的规则,或者这是一个 VS 错误?

4

1 回答 1

3
  Inner^ h; // C2248

这是 C++/CLI 中一个非常常见的错误,在 C# 和 VB.NET 等其他 .NET 语言中是永远不会犯的错误。从声明中自动判断类型是值类型还是引用类型的语言。帽子被添加到 C++/CLI 语法中,使其类似于 C++。

创建对值类型值的引用需要将该值存储在垃圾收集堆上。这称为“装箱转换”,将值嵌入到对象中。否则,产生结构类型继承自 Object 的 ValueType 的错觉的魔法。在少数情况下需要装箱转换,例如调用继承自 System::Object 的虚方法(Equals、GetHashCode、ToString)。编译器在没有你帮助的情况下自动发出装箱转换代码。

像您的陈述一样,故意装箱值几乎没有实际用途。我想不出来,但这可能是由于我缺乏想象力。在访问变量时,您将调用的装箱和拆箱代码看不见,只会增加很多开销,从而减慢您的代码速度。值类型是为了加速代码而发明的,你会想尽可能避免装箱。

解释编译器错误并不是那么容易。有人可能会争辩说,编译器不允许访问使装箱成为可能的类型内部,因为它是私有的。但很难做到这一点,请注意调用i.ToString()会产生相同的错误。虽然它是私有引用类型时很好。可访问性永远不应取决于类型,这种不一致通常称为“错误”;)您可以发布到 connect.microsoft.com 以说明您的情况。

最好的解决方法是理智的:只是不要使用帽子。在需要引用语义时声明引用类型。

于 2013-04-22T17:02:16.360 回答