C# 无法在结构中声明指针变量

本文关键字:声明 指针 变量 结构 | 更新日期: 2023-09-27 18:36:36

我在Visual Studio 2012工作。我只是尝试使用指向相同结构的指针创建结构:

namespace PLT_1_lab {
    class Program {
        struct tNode {
            string oper;
            int level;
            tNode *left;
            tNode *right;
        }
    }
}

在 * 的行中,我得到错误(我已经翻译了 VS,所以它看起来有点不同):

无法获取地址,定义声明指向受控类型的指针的大小("PLT_1_lab。程序注释")

C# 无法在结构中声明指针变量

在 C# 中,如果需要引用机制,通常使用引用类型。

结构是值类型,

但类是引用类型,因此将结构更改为类可以解决问题:

class tNode
{
    string oper;
    int level;
    tNode left;
    tNode right;
}

在此上下文中,空引用等效于C++的空指针。

Matthew的回答可能是最合适的方法,但只是为了解释为什么编译器抱怨...

来自 C# 5 规范的第 18.2 节(指针类型):

指针类型写为非托管类型或关键字 void,后跟 * 标记:

pointer-type:
    unmanaged-type   *
    void   *
unmanaged-type:
    type

指针类型中,在 * 之前指定的类型称为指针类型的参照类型。它表示指针类型的值指向的变量的类型。

非托管类型是指不是引用类型或构造类型

,并且不包含任何嵌套级别的引用类型或构造类型字段的任何类型。换句话说,非托管类型是以下类型之一:

  • 字节、字节、短、ushort、int、uint、长、ulong、char、float、double、十进制或布尔值。
  • 任何枚举类型。
  • 任何指针类型。
  • 任何不是构造类型且仅包含非托管类型的字段的用户定义结构类型。
混合指针和引用的

直观规则是,允许引用(对象)的引用包含指针,但不允许指针的引用包含引用。

所以这里的问题是你的tNode结构包含一个string值。如果没有它 - 并假设您处于不安全的上下文中 - 代码将编译。

不,你不能那样做。

执行此操作的正确方法是使用 class 而不是 struct .

现在,为什么这首先是一个问题?

这在 MSDN 的指针类型下进行了描述:

指针不能指向引用

包含引用的结构,因为即使指针指向对象引用,也可以对对象引用进行垃圾回收。垃圾回收器不会跟踪对象是否由任何指针类型指向

(我的强调)

所以这里的问题不在于指针,而是结构包含一个字符串。

此结构工作:

namespace PLT_1_lab {
    class Program {
        struct tNode {
            // string oper;
            int level;
            tNode *left;
            tNode *right;
        }
    }
}

因此,解决此问题的另一种方法是将指向字符串的指针替换为其他内容,例如可以封送为 BStr 或类似内容的东西,但这一切都取决于您为什么要这样做,而不仅仅是使用class开始。