这个C#结构有什么问题?

时间:2012-03-16 16:44:49

标签: c# struct cycle

注意:我的问题有几个部分。如果您愿意回答每个问题,我会很感激,而不是简单地告诉我该怎么做才能编译。 :)

我对C#没有任何好处。事实上,我不太了解它的原因是我的课程专注于制作有效的算法而不是真正教我们.NET。尽管如此,我们所有的程序都必须用.NET编写,直到现在才出现问题。我有以下代码,但它不会编译,我不明白为什么。我有一种直觉,认为这应该完全改写,但在我这样做之前,我想知道为什么不允许这样做。

结构的要点是创建一个类似于结构的链表,这样我就可以在“列表”的末尾添加另一个节点,然后以相反的顺序遍历和调用节点

private struct BackPointer
{
    public BackPointer previous;
    public string a;
    public string b;
    public BackPointer(BackPointer p, string aa, string bb)
    {
        previous = p;
        a = aa;
        b = bb;
    }
}

然后在我的代码中我有一些影响

BackPointer pointer = new BackPointer();
pointer = new BackPointer(pointer, somestring_a, somestring_b);

我得到的编译错误是Struct member 'MyClass.BackPointer.previous' of type 'MyClass.BackPointer' causes a cycle in the struct layout

这似乎是一个明显的错误。它不喜欢我在同一结构的构造函数中传递结构的事实。但为什么是不允许的?我想这个代码只会在列表中创建一个新节点并返回该节点,并返回前一个节点,但显然不会发生这种情况。那么实际会发生什么呢?最后解决这个问题的推荐方法是什么?我想只是告诉它不受管理只是手动处理我的指针,但我真的只知道如何在C ++中做到这一点。我真的不知道在C#中会出现什么问题

5 个答案:

答案 0 :(得分:10)

那不是指针;它是一个实际嵌入的structstruct s的重点在于它们(几乎)从不指针。

您应该使用class代替。

答案 1 :(得分:6)

  

但为什么不允许这样做?

这是一个结构 - 一种价值类型。这意味着无论您拥有该类型的变量,该变量都包含结构中的所有字段,直接内联。如果某些东西包含自身(或创建一个更复杂的循环),那么你显然无法为它分配足够的空间 - 因为它必须有足够的空间用于其所有字段和另一个自身

  

最后解决此问题的建议方法是什么?

编写一个类而不是结构。然后变量的值将是实例的引用,而不是数据本身。这就是你如何在C#中获得 close 到“指针”的东西。 (请注意,指针和参考文献不同。)

我建议您阅读我在value types and reference types上的文章以获取更多信息 - 这是一个绝对关键主题,需要在C#中理解。

答案 2 :(得分:3)

Backpointer在创建Backpointer之前必须存在,因为没有其他Backpointer(然后需要另一个Backpointer,然后打开),你就不能拥有Backpointer。您根本无法根据创建它的方式创建Backpointer,因为作为结构,Backpointer永远不能为null。

换句话说,使用此代码创建Backpointer是不可能的。编译器知道这一点,因此它迫使你做出一些逻辑上有效的东西。

答案 3 :(得分:0)

结构按值存储。在这种情况下,您的struct在其自身内存储同一结构的另一个实例。该结构本身存储另一个结构,依此类推。因此这是不可能的。这就像说世界上每个人都必须有一个孩子。这是不可能的。

您需要使用的是课程。类通过引用存储,这意味着它不会将类存储在其自身中,它只存储对该类的引用。

答案 4 :(得分:0)

根据定义,CLR structvalue type。这在您的上下文中意味着编译器需要知道该类型的确切布局。但是,它无法知道如何布局包含自身实例的类型 - 这听起来合理吗?将结构更改为类(这使您的BackPointer变为reference type),您将看到它将开箱即用。原因是任何引用类型的实例总是具有相同的布局 - 它基本上只是托管堆的某个位置的“指针”。我强烈建议您阅读一下C#或CLI类型系统的基础知识。