0

I have this question related to Mediator Design Pattern, which is of Behavioral category of GoF. I am trying to write a C# project using Design Pattern principles. Let's say this is a Colleague class:

abstract class Colleague
{
    Mediator mediator;
    // ...
}

And a Mediator class:

class Mediator
{
    List<Colleague> colleagueList;
    // ...
}
  • We can have a lot of colleagues: c1, c2, c3, ...
  • And a single Mediator: mediator

The mediator acts as a central point to allow communication between colleagues. Suppose at some point in our code, some Colleague dies. Will the Mediator object also die?

Ali Sajjad
  • 3,589
  • 1
  • 28
  • 38
  • 3
    An object will be GC'ed only when there are no more references to it. You state that there are multiple colleagues and a single mediator. If that means that all colleagues reference the same instance of a mediator, then mediator will only be GC'ed after the last colleague "dies" (has no more references). – Rufus L Jan 03 '20 at 19:24
  • 1
    @RufusL side note: I'd not use word "disposed" when talking about GC'ed objects as "disposed" has usually special meaning in .NET world (`.Dispose()` called on the object... which is not directly tied to GC) – Alexei Levenkov Jan 03 '20 at 19:28
  • 1
    @AlexeiLevenkov thanks, edited – Rufus L Jan 03 '20 at 19:36
  • 1
    Recommended reading: https://stackoverflow.com/questions/17130382/understanding-garbage-collection-in-net –  Jan 03 '20 at 20:17

2 Answers2

2

In .NET, objects only "die" (get Garbage Collected) when there are no more "rooted" references to them (e.g. circular references alone do not count). So as long as a Colleague is referenced by something else, the Mediator it references will remain.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • 2
    `when there are no more references to them` I think this needs to be amended to say the object can't be reached from the root. If you have two classes A and B that refer to each other, but nothing else references them, they can still be collected. I think. I'm not 100% on this. –  Jan 03 '20 at 19:37
  • 1
    @Amy You're right, 100%. Cyclic references is not enough, you need a "rooted" reference, which includes such things as static fields, live variables on active threads/stacks, etc. (there's a conclusive list somewhere). Cyclic references was a *pain* when Delphi/Object Pascal gained interface support because the "automagic" the compiler inserted managed reference counts, but if you left two objects (or a bigger cycle) referencing each other, none of the objects ever reached 0 references and you could leak memory as a maniac. – Lasse V. Karlsen Jan 03 '20 at 19:38
  • So, if i create a bunch of colleagues and a mediator in main(), the UI class is also a colleague, then I start the program Application.Run(UI); do you think this is safe and a good practice? Will it cause cyclic refrences or something? – Ali Sajjad Jan 04 '20 at 11:15
2

An object will be garbage collected only when there are no more references to it.

You state that there are multiple colleagues and a single mediator, but the question is slightly confusing.

The written part indicates (at least in my interpretation) that all the colleagues have a reference to a single mediator. If that is the case, then mediator will only be GC'ed after the last colleague "dies" (has no more references).

However, based on your code sample, it is the Mediator class itself that holds references to all the colleagues in a private List<Colleague> field. If this is the case, then the Mediator class's lifespan is not dependent on any (or all) instance of the Collegue class. The colleagueList can be null or empty, and the Meditor instance will remain as long as there is still a reference to it somewhere.

Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • 1
    A stretch, but I am not known as "Captain Loophole" for nothing. If a Mediator holds a reference to a Colleague, and the Colleague is garbage collected, then that would be because no live rooted reference exists that leads to it. The fact that the Mediator still holds a reference to it would mean that no live rooted reference exists that reference the Mediator either. In that sense, one could say that if a Colleague being referenced by a Mediator "dies", then the Mediator has to be considered dead as well. As I said, a stretch, but I love to stretch :) – Lasse V. Karlsen Jan 03 '20 at 19:37
  • @LasseV.Karlsen `var meditator = new Mediator { colleagueList = null };` Is it dead? Maybe I'm confused by the term "dead/dies". It's also not clear to me if the `Mediator` holds the *only* reference to the items in the `colleagueList`, nor if the `Colleage` instances are the only things referencing the `Mediator`. I should probably look at the design pattern... :) – Rufus L Jan 03 '20 at 19:48
  • No, you're right in your entire answer, it's just a stretch on how to interpret his question or description of the problem. If you have a Mediator instance that holds a list containing references to one or more Colleague instances, **and those Colleague instances are now eligible for collection**, it must mean the Mediator instance is eligible for collection too, otherwise those Colleague instances wouldn't be. But it was just a silly comment. Never mind me :) – Lasse V. Karlsen Jan 03 '20 at 21:15
  • What if the Colleague does not only die, but is died and then immediately takes the value of another new Colleague(); would this be fine? @LasseV.Karlsen – Ali Sajjad Jan 04 '20 at 11:19