I have two c# classes A,B.
And the code is something like this
Class A
{
B object1;
bool x;
}
Class B
{
A object2;
bool y;
}
Is this even possible? If it is what does this mean? A has object of B which has object of A.... it can go on..
This is indeed possible and in many cases desirable, in such structures such as parent/child relationships, etc. You can even have a member of a class which is of the same class (like in a hierarchical tree).
But what you cannot have is:
class A : B
{
//Implementation of A
}
class B : A
{
//Implementation of B
}
That may be the source of confusion, as the compiler won't be able to tell which is the base class and which is the derived one.
Is this even possible?
Sure, it is possible - you can confirm it by compiling.
If it is what does this mean? A has object of B which has object of A.... it can go on..
To understand this, you need to understand difference between value types (struct
) and reference types (class
).
You can think of struct like single plain piece of memory. All fields in struct are just placed one by one. If some of these fields are also structs, then all fields of that 'child' struct should be placed inside that plain memory piece of 'parent' struct, and so on. So when you declare value-type variable, you are knowing for sure, exactly, how each and every fields of such struct will be aligned in one memory piece. And with struct it is not possible to have cases like you mentioned, when A has field of B which has field of A etc.
Reference types (classes) are different type of thing. When you operate with value of reference type, you operate with actually reference to some memory piece. You can think of reference (while it is not exactly true, but really simplifies things) as just integer number. So whenever you use reference type variable, regardless it's type, you just use it's reference, some int value. Class members itself created in separate memory pieces. So all you have with references in your case - it's something like this:
A => B
B => A
Or, something like this
A <=> B
Nothing wrong with such definition, you have two objects which reference each other, like parent knowing its child, and child knowing its parent.
It is possible because class A should not keep all fields of class B - it just have a reference (integer number) to some other object.
CLR and compiler helps you with identifying types of that references, but basically case of classes referencing each other is the same as classes references just some other classes.
One more significant difference between struct and class - when you declare value type variable, you are actually creating it, reserving memory for it etc; when you declare reference type variable, you are actually creating reference, which will be initialized as null
reference, thus referencing nowhere. So it's easy to create instances of class A and class B - theres fields just reference nowhere; but it's impossible to create such structs A and B, as you would have to create everything at once, which is impossible with limited time and memory.
And small experiment to prove it all. Consider two cases. First like the one in question:
public class Class_A { public Class_B b; }
public class Class_B { public Class_A a; }
It compiles without issues.
And second similar to first, but with structs:
public struct Struct_A { public Struct_B b; }
public struct Struct_B { public Struct_A a; }
First one compiles without issues, second one fails with error:
CS0523: Struct member 'Struct_A.b' of type 'Struct_B' causes a cycle in the struct layout
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With