Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I dispose old object before assigning new object?

Tags:

c#

idisposable

Lets assume we have two class Foo and Bar as given below.

public class Foo
{
    public static Bar BarInstance { get; set; }

    public static void Main()
    {
        AssignBar("A");
        AssignBar("B");
    }

    private static void AssignBar(string name)
    {
        BarInstance = new Bar(name);
    }
}

public class Bar : IDisposable
{
    public Bar(string name)
    {
        Name = name;
    }
    public string Name { get; set; }
    protected virtual void Dispose(bool disposing)
    {
        if (!disposing)
        {
            return;
        }
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

When object A gets replaced by object B. I expect Dispose to called because since there is no reference to Object A exists any more, but it doesn't get called. Could you please explain why?

Should I end up doing CurrentBar.Dispose like below if I want Object A to be disposed.

    private static void AssignBar(string name)
    {
        if (BarInstance != null)
        {
         BarInstance.Dispose();   
        }
        BarInstance = new Bar(name);
    }
like image 626
Carbine Avatar asked Feb 13 '23 07:02

Carbine


1 Answers

It depends on the ownership.

Is Bar given to Foo with the implication that Foo now owns Bar?

If so, then yes, you should call Dispose on the old before assigning a new instance.

Is Bar given to Foo with the implication that it's more of a loan, ie. you can reference and use this object, but it is owned by something else?

If so, then no, you should not call Dispose on the old before assigning a new instance.


Your code is not altogether clear on this point and I would suggest you clean that up, would make it easier to reason about this type in the future.

The way I see it you have 1 of 3 possible scenarios:

  1. Foo always owns Bar. In this case I would put the disposal of the old instance in the setter of the property, or remove the public setter altogether if the only way to get a new Bar instance into it is through the method you have declared.
  2. Foo never owns Bar. In this case I would not add any code that disposes of the old instance, but then I question the existence of that method. In this case it is likely nobody would really own the newly constructed instance.
  3. Foo only owns Bar instances created through your method, but not instances given to it through the public setter. In this case I would add a new field that tracks whether Foo owns Bar or not, and set this to true in the method, and clear it in the property setter.

Dispose is not special in any way, from the C# standpoint it is just another method, as such there is nothing automatic that will call this method.

However, if the object references unmanaged resources, when the object at some point becomes eligible for collection, its finalizer will be executed releasing those unmanaged resources. However, to deterministically release them when you know they are no longer needed, you need to call Dispose.

like image 126
Lasse V. Karlsen Avatar answered Feb 15 '23 10:02

Lasse V. Karlsen