How to implement Dispose on object creates other disposables
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
add a comment |
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
1
You're right, but keep in mind that if you create a class derived fromMyDisposableContainer
you've a broken implementation. You've two options make your classsealed
or implement a finalizer and fullDispose
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 ofDispose
by consumers, an exception thrown inDispose
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
add a comment |
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
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
c# dispose idisposable
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 fromMyDisposableContainer
you've a broken implementation. You've two options make your classsealed
or implement a finalizer and fullDispose
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 ofDispose
by consumers, an exception thrown inDispose
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
add a comment |
1
You're right, but keep in mind that if you create a class derived fromMyDisposableContainer
you've a broken implementation. You've two options make your classsealed
or implement a finalizer and fullDispose
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 ofDispose
by consumers, an exception thrown inDispose
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
add a comment |
1 Answer
1
active
oldest
votes
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 20 '18 at 15:18
Dmytro MukalovDmytro Mukalov
45937
45937
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 classsealed
or implement a finalizer and fullDispose
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 inDispose
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