2个C#类作为成员互相包含

时间:2014-03-18 11:28:24

标签: c# .net class oop c#-3.0

我有两个c#类A,B。

代码是这样的

Class A
{
     B object1;
     bool x;
}

Class B       
{     
    A object2;        
    bool y;
}

这甚至可能吗? 如果这是什么意思? A具有B的对象,其具有A的对象....它可以继续...

5 个答案:

答案 0 :(得分:4)

在父/子关系等结构中,这确实是可能的,并且在许多情况下是可取的。您甚至可以拥有同一类的类的成员(如在分层树中)。

但你不能拥有的是:

class A : B
{
    //Implementation of A
}

class B : A
{
    //Implementation of B
}

这可能是混淆的根源,因为编译器将无法分辨哪个是基类,哪个是派生类。

答案 1 :(得分:4)

  

这甚至可能吗?

当然,有可能 - 您可以通过编译来确认。

  
    

如果这是什么意思? A具有B的对象,其具有A的对象....它可以继续...

  

要理解这一点,您需要了解值类型(struct)和引用类型(class)之间的区别。

您可以将结构视为单个简单的内存片段。 struct中的所有字段都是逐个放置的。如果其中一些字段也是结构,那么该子字段的所有字段都是'结构应该放在父母的简单记忆片中。结构,等等。因此,当您声明值类型变量时,您确切地知道这样的结构的每个字段将如何在一个内存块中对齐。使用结构时,不可能可能会出现像你提到的情况,当A的B字段有A等字段时。

引用类型(类)是不同类型的东西。当您使用参考类型的值进行操作时,您可以使用实际引用操作某个内存块。您可以将引用(虽然它不完全正确,但实际上简化了事情)视为整数。因此,无论何时使用引用类型变量,无论它的类型如何,您只需使用它的引用,一些int值。类成员本身在单独的内存块中创建。所以你所拥有的只有你的案例 - 它是这样的:

A => B
B => A

或者,像这样

A <=> B

这样的定义没有错,你有两个相互引用的对象,比如父亲知道它的孩子,孩子知道它的父母。

这是可能的,因为A类不应该保留B类的所有字段 - 它只有引用(整数)到其他对象。

CLR和编译器可以帮助您识别引用的类型,但基本上引用彼此的类的情况与引用其他类的类相同。

struct和class之间的另一个重要区别 - 当你声明值类型变量时,你实际上是创建它,为它保留内存等;当您声明引用类型变量时,您实际上是创建引用,它将被初始化为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:结构成员&#39; Struct_A.b&#39;类型&#39; Struct_B&#39;导致结构布局中的循环

答案 2 :(得分:0)

您将拥有循环/循环依赖。

答案 3 :(得分:0)

但是,c#中的类定义关键字可能是class而不是Class

答案 4 :(得分:0)

如果这两个类在不同的dll中,你会遇到很多dll循环引用相关的问题(避免)。

如果序列化(Circular Reference when using XML Serialization?

,您还创建了循环引用问题

否则,在大多数情况下,它是一个有效且有用的定义。