1

There are already a couple of questions similar to this one: this and this

In particular I quote Marc Gravell's answer (here):

If you have A publishing an event, and B subscribing to an event (the handler), then it is only a problem not to unsubscribe if A is going to live a lot longer than B.

But I could not find any mention to the special case when the event source and the handler are the same reference, for example:

class Foo
{
    public event Action SomeEvent;

    public Foo() => SomeEvent += OnSomeEventHappened; //should I unsubscribe somewhere?

    private void OnSomeEventHappened(){}
}

I just want to be sure there is no hidden issue with the above code. As far as I know I may never unsubscribe from that event since both the subscriber and the publisher are exactly the same instance.

Would not subscribing prevent my Foo instance from being garbage collected?

taquion
  • 2,667
  • 2
  • 18
  • 29
  • 1
    At a fairly naive level, it would seem that still answers your question. If it's only a problem if the publisher is going to live a lot longer than the handler, I wouldn't think there'd be a problem at all, since obviously your publisher and subscriber live the same amount of time (as they are the same object). But I could be **way** oversimplifying how I see this. – Broots Waymb Dec 03 '19 at 17:48
  • 3
    I wouldn't necessarily see this as a "special case". Marc's quote would still apply, it's just that you won't run into an instance of A outliving B because A = B. – Code Stranger Dec 03 '19 at 17:53
  • I am not sure if those questions's anwers apply, and that is why I am asking. I just want to be sure that having a reference to itself does not prevent garbage collection – taquion Dec 03 '19 at 17:56

1 Answers1

2

This doesn't appear to be necessary.
Based off your comment it sounds like you're most worried about garbage collection (or possible lack of).

I just wrote up a super quick test app inspired by this answer in order to test whether the object was garbage collected. It appears to have been.

Here is the code I used to test (running in Release), using the same code you have for your Foo class (left out for simplicity):

class Program
{
    [STAThread]
    static void Main()
    {
        Foo foo = new Foo();

        WeakReference fooRef = new WeakReference(foo);

        Console.WriteLine(fooRef.IsAlive); //Displays "True"

        foo = null;
        GC.Collect();

        Console.WriteLine(fooRef.IsAlive); //Displays "False"

        Console.ReadKey();
    }
}  

Output:

True
False

Here's a fiddle that seems to do the job as well (assuming it doesn't have its own garbage collection quirks... I'm not a super experienced "fiddler").

Broots Waymb
  • 4,713
  • 3
  • 28
  • 51
  • Yup, just verified that this works in Release mode. As a [comment](https://stackoverflow.com/questions/15460362/how-to-tell-if-an-object-has-been-garbage-collected/15460363#comment100213051_15460363) on the linked answers addresses, there are "quirks" to how it works in debug mode, so without jumping through those hoops for the sake of this test, it seems fair. I didn't even know about `WeakReference`... – Code Stranger Dec 03 '19 at 18:16