How to implement Dispose on object creates other disposables












3















Given following class:



public class MyDisposableContainer : IDisposable
{
readonly List<IDisposable> _chidlren = new List<IDisposable>();

public void Add() => _children.Add(new FileSystemWachter());
}


I'm not sure how should I implement the Disposable interface.



Either:



 public void Dispose() => _children.ForEach(item => item.Dispose());


or



public void Dispose()
{
// Dispose of unmanaged resources.
Dispose(true);
// Suppress finalization.
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_children.ForEach(item => item.Dispose());
}
}


In my case, the children are FileSystemWatcher which uses some unmanaged resources, so I guess it implements the disposable pattern together with finalizer.



I guess, the second, longer approach is not necessary, because it Dispose(true) will be called only on explicit Dispose() call anyway. Am I right?










share|improve this question


















  • 1





    You're right, but keep in mind that if you create a class derived from MyDisposableContainer you've a broken implementation. You've two options make your class sealed or implement a finalizer and full Dispose pattern.

    – Alessandro D'Andria
    Nov 20 '18 at 10:22











  • Ah, ok, that makes sense. However, it is necessary to implement finalizer in the base class (MyDisposableContainer in my case)? Somehow I don't see why it is necessary when other classes inherits from it

    – Liero
    Nov 20 '18 at 10:38













  • Assuming you need a finalizer is wrong 99.9% of the time. It is here too, FSW already has its own finalizer.

    – Hans Passant
    Nov 20 '18 at 11:02











  • You don't need a finalizer in the base class. Consider having a finalizer only for scenarios when you need some guarantee for releasing resources which couldn't be released other way for any of reason (not proper usage of Dispose by consumers, an exception thrown in Dispose method, etc.). As CLR takes care of managed resources the only resources which is subject of such scenarios are unmanaged resources.

    – Dmytro Mukalov
    Nov 20 '18 at 11:10













  • @DmytroMukalov: it would be nice of you, if you summarized the comments in an answer

    – Liero
    Nov 20 '18 at 13:54
















3















Given following class:



public class MyDisposableContainer : IDisposable
{
readonly List<IDisposable> _chidlren = new List<IDisposable>();

public void Add() => _children.Add(new FileSystemWachter());
}


I'm not sure how should I implement the Disposable interface.



Either:



 public void Dispose() => _children.ForEach(item => item.Dispose());


or



public void Dispose()
{
// Dispose of unmanaged resources.
Dispose(true);
// Suppress finalization.
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_children.ForEach(item => item.Dispose());
}
}


In my case, the children are FileSystemWatcher which uses some unmanaged resources, so I guess it implements the disposable pattern together with finalizer.



I guess, the second, longer approach is not necessary, because it Dispose(true) will be called only on explicit Dispose() call anyway. Am I right?










share|improve this question


















  • 1





    You're right, but keep in mind that if you create a class derived from MyDisposableContainer you've a broken implementation. You've two options make your class sealed or implement a finalizer and full Dispose pattern.

    – Alessandro D'Andria
    Nov 20 '18 at 10:22











  • Ah, ok, that makes sense. However, it is necessary to implement finalizer in the base class (MyDisposableContainer in my case)? Somehow I don't see why it is necessary when other classes inherits from it

    – Liero
    Nov 20 '18 at 10:38













  • Assuming you need a finalizer is wrong 99.9% of the time. It is here too, FSW already has its own finalizer.

    – Hans Passant
    Nov 20 '18 at 11:02











  • You don't need a finalizer in the base class. Consider having a finalizer only for scenarios when you need some guarantee for releasing resources which couldn't be released other way for any of reason (not proper usage of Dispose by consumers, an exception thrown in Dispose method, etc.). As CLR takes care of managed resources the only resources which is subject of such scenarios are unmanaged resources.

    – Dmytro Mukalov
    Nov 20 '18 at 11:10













  • @DmytroMukalov: it would be nice of you, if you summarized the comments in an answer

    – Liero
    Nov 20 '18 at 13:54














3












3








3








Given following class:



public class MyDisposableContainer : IDisposable
{
readonly List<IDisposable> _chidlren = new List<IDisposable>();

public void Add() => _children.Add(new FileSystemWachter());
}


I'm not sure how should I implement the Disposable interface.



Either:



 public void Dispose() => _children.ForEach(item => item.Dispose());


or



public void Dispose()
{
// Dispose of unmanaged resources.
Dispose(true);
// Suppress finalization.
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_children.ForEach(item => item.Dispose());
}
}


In my case, the children are FileSystemWatcher which uses some unmanaged resources, so I guess it implements the disposable pattern together with finalizer.



I guess, the second, longer approach is not necessary, because it Dispose(true) will be called only on explicit Dispose() call anyway. Am I right?










share|improve this question














Given following class:



public class MyDisposableContainer : IDisposable
{
readonly List<IDisposable> _chidlren = new List<IDisposable>();

public void Add() => _children.Add(new FileSystemWachter());
}


I'm not sure how should I implement the Disposable interface.



Either:



 public void Dispose() => _children.ForEach(item => item.Dispose());


or



public void Dispose()
{
// Dispose of unmanaged resources.
Dispose(true);
// Suppress finalization.
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_children.ForEach(item => item.Dispose());
}
}


In my case, the children are FileSystemWatcher which uses some unmanaged resources, so I guess it implements the disposable pattern together with finalizer.



I guess, the second, longer approach is not necessary, because it Dispose(true) will be called only on explicit Dispose() call anyway. Am I right?







c# dispose idisposable






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 20 '18 at 10:11









LieroLiero

9,608644113




9,608644113








  • 1





    You're right, but keep in mind that if you create a class derived from MyDisposableContainer you've a broken implementation. You've two options make your class sealed or implement a finalizer and full Dispose pattern.

    – Alessandro D'Andria
    Nov 20 '18 at 10:22











  • Ah, ok, that makes sense. However, it is necessary to implement finalizer in the base class (MyDisposableContainer in my case)? Somehow I don't see why it is necessary when other classes inherits from it

    – Liero
    Nov 20 '18 at 10:38













  • Assuming you need a finalizer is wrong 99.9% of the time. It is here too, FSW already has its own finalizer.

    – Hans Passant
    Nov 20 '18 at 11:02











  • You don't need a finalizer in the base class. Consider having a finalizer only for scenarios when you need some guarantee for releasing resources which couldn't be released other way for any of reason (not proper usage of Dispose by consumers, an exception thrown in Dispose method, etc.). As CLR takes care of managed resources the only resources which is subject of such scenarios are unmanaged resources.

    – Dmytro Mukalov
    Nov 20 '18 at 11:10













  • @DmytroMukalov: it would be nice of you, if you summarized the comments in an answer

    – Liero
    Nov 20 '18 at 13:54














  • 1





    You're right, but keep in mind that if you create a class derived from MyDisposableContainer you've a broken implementation. You've two options make your class sealed or implement a finalizer and full Dispose pattern.

    – Alessandro D'Andria
    Nov 20 '18 at 10:22











  • Ah, ok, that makes sense. However, it is necessary to implement finalizer in the base class (MyDisposableContainer in my case)? Somehow I don't see why it is necessary when other classes inherits from it

    – Liero
    Nov 20 '18 at 10:38













  • Assuming you need a finalizer is wrong 99.9% of the time. It is here too, FSW already has its own finalizer.

    – Hans Passant
    Nov 20 '18 at 11:02











  • You don't need a finalizer in the base class. Consider having a finalizer only for scenarios when you need some guarantee for releasing resources which couldn't be released other way for any of reason (not proper usage of Dispose by consumers, an exception thrown in Dispose method, etc.). As CLR takes care of managed resources the only resources which is subject of such scenarios are unmanaged resources.

    – Dmytro Mukalov
    Nov 20 '18 at 11:10













  • @DmytroMukalov: it would be nice of you, if you summarized the comments in an answer

    – Liero
    Nov 20 '18 at 13:54








1




1





You're right, but keep in mind that if you create a class derived from MyDisposableContainer you've a broken implementation. You've two options make your class sealed or implement a finalizer and full Dispose pattern.

– Alessandro D'Andria
Nov 20 '18 at 10:22





You're right, but keep in mind that if you create a class derived from MyDisposableContainer you've a broken implementation. You've two options make your class sealed or implement a finalizer and full Dispose pattern.

– Alessandro D'Andria
Nov 20 '18 at 10:22













Ah, ok, that makes sense. However, it is necessary to implement finalizer in the base class (MyDisposableContainer in my case)? Somehow I don't see why it is necessary when other classes inherits from it

– Liero
Nov 20 '18 at 10:38







Ah, ok, that makes sense. However, it is necessary to implement finalizer in the base class (MyDisposableContainer in my case)? Somehow I don't see why it is necessary when other classes inherits from it

– Liero
Nov 20 '18 at 10:38















Assuming you need a finalizer is wrong 99.9% of the time. It is here too, FSW already has its own finalizer.

– Hans Passant
Nov 20 '18 at 11:02





Assuming you need a finalizer is wrong 99.9% of the time. It is here too, FSW already has its own finalizer.

– Hans Passant
Nov 20 '18 at 11:02













You don't need a finalizer in the base class. Consider having a finalizer only for scenarios when you need some guarantee for releasing resources which couldn't be released other way for any of reason (not proper usage of Dispose by consumers, an exception thrown in Dispose method, etc.). As CLR takes care of managed resources the only resources which is subject of such scenarios are unmanaged resources.

– Dmytro Mukalov
Nov 20 '18 at 11:10







You don't need a finalizer in the base class. Consider having a finalizer only for scenarios when you need some guarantee for releasing resources which couldn't be released other way for any of reason (not proper usage of Dispose by consumers, an exception thrown in Dispose method, etc.). As CLR takes care of managed resources the only resources which is subject of such scenarios are unmanaged resources.

– Dmytro Mukalov
Nov 20 '18 at 11:10















@DmytroMukalov: it would be nice of you, if you summarized the comments in an answer

– Liero
Nov 20 '18 at 13:54





@DmytroMukalov: it would be nice of you, if you summarized the comments in an answer

– Liero
Nov 20 '18 at 13:54












1 Answer
1






active

oldest

votes


















-1














So the brief answer is: yes you can use the simple form



public void Dispose() => _children.ForEach(item => item.Dispose());



in your case.



The extended form



public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
...
}
}


which is basic implementation of basic dispose pattern is bit redundant here but it's suggested as a good manner and basement for future possible extensions of the class by means of inheritance (unless it's sealed).



The longer answer implies clarification of possible scenarios related to disposal and best practices for that. An object destruction process deals with two types of resources managed and managed. Managed resources can be successfully handled by GC so we mostly shouldn't bother too much with that, while unmanaged resources release is a responsibility of calling code as GC cannot track their allocations and de-allocations. IDisposable interface purpose is to address the scenarios when unmanaged resources de-allocation should be handled in some object or objects hierarchy. Now as for the possible cases:




  • if your class directly retains unmanaged resources it's recommended to use extended finalizable dispose pattern with finalizer in order to cover cases of improper utilization of the class by external consumers or exceptional situations to get guaranteed resources de-allocation by means of either Dispose or a finalizer;

  • if your class holds other IDisposable but doesn't hold unmanaged resources directly the recommended way is using basic dispose pattern without a finalizer;


Couple of notes about destruction responsibility separation as it popped up in the comments. Each class should be responsible for clear handling of release for only those resources which it directly retains. It shouldn't bother with trying to handle release scenarios for underlying objects in any other way other than by using thier publicly exposed contracts, that is via IDisposable or any other interface and shouldn't make any assumptions beyond of these public contracts.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53390665%2fhow-to-implement-dispose-on-object-creates-other-disposables%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    -1














    So the brief answer is: yes you can use the simple form



    public void Dispose() => _children.ForEach(item => item.Dispose());



    in your case.



    The extended form



    public void Dispose()
    {
    Dispose(true);
    GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
    if (disposing)
    {
    ...
    }
    }


    which is basic implementation of basic dispose pattern is bit redundant here but it's suggested as a good manner and basement for future possible extensions of the class by means of inheritance (unless it's sealed).



    The longer answer implies clarification of possible scenarios related to disposal and best practices for that. An object destruction process deals with two types of resources managed and managed. Managed resources can be successfully handled by GC so we mostly shouldn't bother too much with that, while unmanaged resources release is a responsibility of calling code as GC cannot track their allocations and de-allocations. IDisposable interface purpose is to address the scenarios when unmanaged resources de-allocation should be handled in some object or objects hierarchy. Now as for the possible cases:




    • if your class directly retains unmanaged resources it's recommended to use extended finalizable dispose pattern with finalizer in order to cover cases of improper utilization of the class by external consumers or exceptional situations to get guaranteed resources de-allocation by means of either Dispose or a finalizer;

    • if your class holds other IDisposable but doesn't hold unmanaged resources directly the recommended way is using basic dispose pattern without a finalizer;


    Couple of notes about destruction responsibility separation as it popped up in the comments. Each class should be responsible for clear handling of release for only those resources which it directly retains. It shouldn't bother with trying to handle release scenarios for underlying objects in any other way other than by using thier publicly exposed contracts, that is via IDisposable or any other interface and shouldn't make any assumptions beyond of these public contracts.






    share|improve this answer




























      -1














      So the brief answer is: yes you can use the simple form



      public void Dispose() => _children.ForEach(item => item.Dispose());



      in your case.



      The extended form



      public void Dispose()
      {
      Dispose(true);
      GC.SuppressFinalize(this);
      }

      protected virtual void Dispose(bool disposing)
      {
      if (disposing)
      {
      ...
      }
      }


      which is basic implementation of basic dispose pattern is bit redundant here but it's suggested as a good manner and basement for future possible extensions of the class by means of inheritance (unless it's sealed).



      The longer answer implies clarification of possible scenarios related to disposal and best practices for that. An object destruction process deals with two types of resources managed and managed. Managed resources can be successfully handled by GC so we mostly shouldn't bother too much with that, while unmanaged resources release is a responsibility of calling code as GC cannot track their allocations and de-allocations. IDisposable interface purpose is to address the scenarios when unmanaged resources de-allocation should be handled in some object or objects hierarchy. Now as for the possible cases:




      • if your class directly retains unmanaged resources it's recommended to use extended finalizable dispose pattern with finalizer in order to cover cases of improper utilization of the class by external consumers or exceptional situations to get guaranteed resources de-allocation by means of either Dispose or a finalizer;

      • if your class holds other IDisposable but doesn't hold unmanaged resources directly the recommended way is using basic dispose pattern without a finalizer;


      Couple of notes about destruction responsibility separation as it popped up in the comments. Each class should be responsible for clear handling of release for only those resources which it directly retains. It shouldn't bother with trying to handle release scenarios for underlying objects in any other way other than by using thier publicly exposed contracts, that is via IDisposable or any other interface and shouldn't make any assumptions beyond of these public contracts.






      share|improve this answer


























        -1












        -1








        -1







        So the brief answer is: yes you can use the simple form



        public void Dispose() => _children.ForEach(item => item.Dispose());



        in your case.



        The extended form



        public void Dispose()
        {
        Dispose(true);
        GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
        if (disposing)
        {
        ...
        }
        }


        which is basic implementation of basic dispose pattern is bit redundant here but it's suggested as a good manner and basement for future possible extensions of the class by means of inheritance (unless it's sealed).



        The longer answer implies clarification of possible scenarios related to disposal and best practices for that. An object destruction process deals with two types of resources managed and managed. Managed resources can be successfully handled by GC so we mostly shouldn't bother too much with that, while unmanaged resources release is a responsibility of calling code as GC cannot track their allocations and de-allocations. IDisposable interface purpose is to address the scenarios when unmanaged resources de-allocation should be handled in some object or objects hierarchy. Now as for the possible cases:




        • if your class directly retains unmanaged resources it's recommended to use extended finalizable dispose pattern with finalizer in order to cover cases of improper utilization of the class by external consumers or exceptional situations to get guaranteed resources de-allocation by means of either Dispose or a finalizer;

        • if your class holds other IDisposable but doesn't hold unmanaged resources directly the recommended way is using basic dispose pattern without a finalizer;


        Couple of notes about destruction responsibility separation as it popped up in the comments. Each class should be responsible for clear handling of release for only those resources which it directly retains. It shouldn't bother with trying to handle release scenarios for underlying objects in any other way other than by using thier publicly exposed contracts, that is via IDisposable or any other interface and shouldn't make any assumptions beyond of these public contracts.






        share|improve this answer













        So the brief answer is: yes you can use the simple form



        public void Dispose() => _children.ForEach(item => item.Dispose());



        in your case.



        The extended form



        public void Dispose()
        {
        Dispose(true);
        GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
        if (disposing)
        {
        ...
        }
        }


        which is basic implementation of basic dispose pattern is bit redundant here but it's suggested as a good manner and basement for future possible extensions of the class by means of inheritance (unless it's sealed).



        The longer answer implies clarification of possible scenarios related to disposal and best practices for that. An object destruction process deals with two types of resources managed and managed. Managed resources can be successfully handled by GC so we mostly shouldn't bother too much with that, while unmanaged resources release is a responsibility of calling code as GC cannot track their allocations and de-allocations. IDisposable interface purpose is to address the scenarios when unmanaged resources de-allocation should be handled in some object or objects hierarchy. Now as for the possible cases:




        • if your class directly retains unmanaged resources it's recommended to use extended finalizable dispose pattern with finalizer in order to cover cases of improper utilization of the class by external consumers or exceptional situations to get guaranteed resources de-allocation by means of either Dispose or a finalizer;

        • if your class holds other IDisposable but doesn't hold unmanaged resources directly the recommended way is using basic dispose pattern without a finalizer;


        Couple of notes about destruction responsibility separation as it popped up in the comments. Each class should be responsible for clear handling of release for only those resources which it directly retains. It shouldn't bother with trying to handle release scenarios for underlying objects in any other way other than by using thier publicly exposed contracts, that is via IDisposable or any other interface and shouldn't make any assumptions beyond of these public contracts.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 15:18









        Dmytro MukalovDmytro Mukalov

        45937




        45937
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53390665%2fhow-to-implement-dispose-on-object-creates-other-disposables%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Tangent Lines Diagram Along Smooth Curve

            Yusuf al-Mu'taman ibn Hud

            Zucchini