Why is there no cyclic layout issue for classes in C#?

有些话、适合烂在心里 提交于 2019-12-09 16:29:13

问题


public struct Unit
{
    Unit u;
}

Causes:

Struct member 'Unit.u' of type 'Unit' causes a cycle in the struct layout.

But

public class Unit
{
    Unit u;
}

compiles. I understand the problem I suppose. An endless cycle will be formed when referencing a Unit object since it will have to initialize another member Unit and so on. But why does the compiler restrict the problem just for structs? Doesn't the issue persist for class too? Am I missing something?


回答1:


The problem is in terms of layout.

When Unit is a struct, any value for a Unit would have to contain another value of the same type (and thus the same size), ad infinitum. That's impossible. I suppose you could argue that with no other fields, the fields for Unit should take up no memory, so you could contain it within itself - but I believe the way the CLR works ensures that all structs take up at least 1 byte...

When Unit is a class, a Unit object only has to contain a reference to another Unit object. No storage problems, and the value can be null to start with.

Think of it this way: you can't have a house which contains another house constructed from the same blueprint, but you can certainly have a house which contains a piece of paper with a similar house's address on it...




回答2:


Classes are reference types, so I imagine the difference is that in the class example, it only has to save a reference to another instance. For your struct, a value type, it would need to include the entire structure again, hence an infinite loop.




回答3:


The struct is automatically initialized with a value, so in your example a Unit value contains a Unit value, which contains a Unit value, which contains a Unit value, etc...

Your class example only initializes the reference to null, which does not have an infinite regress. You would however encounter a similar problem if you did the following:

class Unit
{
   Unit mUnit = new Unit();
}

Now, constructing a Unit constructs a Unit, which constructs a Unit, etc... In this case, you will encounter a runtime stack overflow exception if/when you try to instantiate a Unit object.

I thought that you might be able to avoid the struct issue by using a nullable type, but the problem remains. I believe this is due to the fact that a nullable struct is still instantiated when set to null.




回答4:


Because Struct are value type. Unit can hold the value as itself? I think this is not posible.

But when Unit is class, class are reference type. Unit object can hold a reference to the another Unit object. It is fine.



来源:https://stackoverflow.com/questions/14309264/why-is-there-no-cyclic-layout-issue-for-classes-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!