问题
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