c# - Circular reference in same assembly a bad thing? -


assume have following classes in same assembly

public class parentclass : idisposable {   public childclass child   {     { return _child; }   } }     public class childclass  {    public parentclass parent    {      { return _parent; }      set { _parent= value; }    }     public childclass (parentclass parent)    {      parent= parent;    }  } 

correct me if wrong bad design. lead memory leak or other unforseen issues later on? apparently garbage collector capable of handling such kind of circular references.

edit

what if 2 classes end getting used in other class?

parentclass objp = new parentclass (); childclass objc =new childclass(objp); objp.child = objc; 

thoughts please ....

don't worry garbage collector; handles reference graphs arbitrary topologies ease. worry writing objects lend creating bugs making easy violate invariants.

this questionable design not because stresses gc -- not -- rather because not enforce desired semantic invariant: if x parent of y, y must child of x.

it can quite tricky write classes maintain consistent parent-child relationships. on roslyn team build two trees. "real" tree has child references; no child knows parent. layer "facade" tree on top of enforces consistency of parent-child relationship: when ask parent node child, creates facade on top of real child , sets parent of facade object true parent.

update: commenter brian asks more details. here's sketch of how might implement "red" facade child , parent references on "green" tree contains child references. in system impossible make inconsistent parent-child relationship, can see in test code @ bottom.

(we call these "red" , "green" trees because when drawing data structure on whiteboard, marker colours used.)

using system;  interface ivalue { string value { get; } } interface iparent : ivalue { ichild child { get; } } interface ichild : ivalue { iparent parent { get; } }  abstract class hasvalue : ivalue {     private string value;     public hasvalue(string value)     {         this.value = value;     }     public string value { { return value; } } }  sealed class greenchild : hasvalue {     public greenchild(string value) : base(value) {} }  sealed class greenparent : hasvalue {     private greenchild child;     public greenchild child { { return child; } }     public greenparent(string value, greenchild child) : base(value)     {           this.child = child;      }      public iparent makefacade() { return new redparent(this); }      private sealed class redparent : iparent     {         private greenparent greenparent;         private redchild redchild;         public redparent(greenparent parent)          {              this.greenparent = parent;              this.redchild = new redchild(this);         }         public ichild child { { return redchild; } }         public string value { { return greenparent.value; } }          private sealed class redchild : ichild         {             private redparent redparent;             public redchild(redparent redparent)             {                 this.redparent = redparent;             }             public iparent parent { { return redparent; } }             public string value              {                                   {                      return redparent.greenparent.child.value;                  }              }         }     } } class p {     public static void main()     {         var greenchild1 = new greenchild("child1");         var greenparent1 = new greenparent("parent1", greenchild1);         var greenparent2 = new greenparent("parent2", greenchild1);          var redparent1 = greenparent1.makefacade();         var redparent2 = greenparent2.makefacade();          console.writeline(redparent1.value); // parent1         console.writeline(redparent1.child.parent.value); // parent1 !         console.writeline(redparent2.value); // parent2         console.writeline(redparent2.child.parent.value); // parent2 !          // see how goes? redparent1 , redparent2 disagree on         // parent of greenchild1 is, **but self-consistent**.         // report parent of child themselves.     } } 

Comments

Popular posts from this blog

delphi - How to convert bitmaps to video? -

jasper reports - Fixed header in Excel using JasperReports -

python - ('The SQL contains 0 parameter markers, but 50 parameters were supplied', 'HY000') or TypeError: 'tuple' object is not callable -