c#类将彼此作为成员包含
本文关键字:成员 包含 | 更新日期: 2023-09-27 17:50:49
我有两个c#类A, b。
代码是这样的
Class A
{
B object1;
bool x;
}
Class B
{
A object2;
bool y;
}
这可能吗?如果是,这意味着什么?A有B的对象B有A的对象....
在父/子关系等结构中,这确实是可能的,并且在许多情况下是理想的。你甚至可以让一个类的成员属于同一个类(就像在层次树中一样)。
但是你不能拥有的是:
class A : B
{
//Implementation of A
}
class B : A
{
//Implementation of B
}
这可能是混淆的根源,因为编译器将无法分辨哪个是基类,哪个是派生类。
这可能吗?
当然,这是可能的——你可以通过编译来确认。
如果是,这是什么意思?A有B的对象B有A的对象....
要理解这一点,您需要理解值类型(struct
)和引用类型(class
)之间的区别。
你可以把结构体想象成一块普通的内存。struct中的所有字段都是一个接一个地放置的。如果其中一些字段也是结构体,那么该"子"结构体的所有字段都应该放在"父"结构体的普通内存块中,依此类推。因此,当您声明值类型变量时,您确切地知道这种结构体的每个字段将如何在一个内存块中对齐。对于struct, 不可能有你提到的情况,当A有B的字段,B有A的字段等。
引用类型(类)是不同类型的东西。当使用引用类型的值进行操作时,实际上是使用对某个内存块的引用进行操作。您可以将引用(虽然不完全正确,但确实简化了事情)视为整数。当你使用引用类型变量时,不管它的类型是什么,你只是使用它的引用,一些int值。类成员本身在单独的内存块中创建。所以在你的例子中,所有的引用都是这样的:A => B
B => A
或者像这样
A <=> B
这样的定义没有错,你有两个相互引用的对象,就像父对象知道它的子对象,而子对象知道它的父对象。
这是可能的,因为类A不应该保留类B的所有字段-它只具有对其他对象的引用(整数)。
CLR和编译器帮助你识别这些引用的类型,但基本上,类相互引用的情况与类引用其他类的情况相同。
结构和类之间的一个更重要的区别-当你声明值类型变量时,你实际上是创建它,为它保留内存等;当你声明引用类型变量时,你实际上是在创建引用,它将被初始化为null
引用,因此无处引用。所以创建类A和类B的实例很容易——这些字段没有引用;但是创建这样的结构体A和B是不可能的,因为你必须一次创建所有的东西,这在有限的时间和内存下是不可能的。
和一个小实验来证明这一切。考虑两种情况。首先像问题中的那个:
public class Class_A { public Class_B b; }
public class Class_B { public Class_A a; }
编译时没有问题。
第二个与第一个类似,但使用结构体:
public struct Struct_A { public Struct_B b; }
public struct Struct_B { public Struct_A a; }
第一个编译没有问题,第二个错误:
CS0523: Struct member 'Struct_A. '类型'Struct_B'的b'导致结构布局中的循环
你将有循环/循环依赖
这是可能的,但是c#中类定义的关键字是class
而不是Class
。
如果这两个类在不同的dll中,你会遇到很多与dll循环引用相关的问题(避免)。
您还创建了一个循环引用问题,如果您序列化(循环引用时使用XML序列化?)
在大多数情况下,