472,328 Members | 1,258 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,328 software developers and data experts.

IDisposable, "using" keyword and "Close()" methods

Hi all,
coming from an unmanaged programming background, I took my time to
sort out the IDisposable and finalizer patterns. Just when I thought
I had it all conceptually neatly arranged, the "Close()" methods reared
their ugly (at least it would seem...)heads.

I was happily delving away in the .NET framework, investigating the
stream classes with the msdn and Lutz Roeder's .NET reflector, when I
stumbled upon the following:

(using BinaryReader as an example, though not the only "bad guy")
1) The MSDN : "This implementation of Close calls the Dispose method
passing a true value."
2) the Close() method in the BinaryReader is marked virtual
3) the "using" keyword will invoke the implemented IDisposable.Dispose()
on the expression you want to dispose

it looks to me like the "using" keyword in this case could be
potentially very dangerous. Nothing prevents me from descending from
BinaryReader, override the Close() method, and do some essential extra
work (marking a flag, log something, whatever), and everyone using my
class with the "using" keyword would have (at best) unnoticed side effects.

I can see the need for IDisposable, I can see the need for virtual
methods that will call Dispose on your behalf, but I don't get the need
for a "using" keyword for calling Dispose() for you, when (at least in
some cases) you might be short-circuiting things because you should've
called "Close()" (or whatever they choose to call it). The documentation
in the MSDN doesn't mention anywhere (that is, I couldn't find it...)
that you should use Close() instead of
Dispose() from the implemented interface.

Is (or should I mark) the "using" keyword "potentially dangerous"?

Thanks in advance,

Willem van Rumpt
Nov 16 '05 #1
7 2881
Willem van Rumpt <no***********@no.thelandslide.spam.com> wrote:

<snip>
Is (or should I mark) the "using" keyword "potentially dangerous"?


No - failing to use "using" is potentially dangerous.

If you want to write a class which doesn't implement Dispose
appropriately - i.e. if calling Dispose isn't enough to clean up the
unmanaged resources - that's fine. There's nothing to stop you from
writing badly behaved classes in .NET - but it *is* relatively easy to
write *well*-behaved classes instead.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #2
Hi Willem,

Close methods is added to stream, reader, writer, etc classes just because
it makes more sense for those classes to be closed. Why is it virtual?
Simply because normally when somethig work with streams the idea is to
abstract where the data actually goes it could be memory, disk, db, etc. So
normaly the code deals with the base class. In .NET disposing is the way to
release unmanaged resources, so you should write your classes with that in
mind.
Some times Close behaves differently according to some conditions. For
example look at the Form class. When the form is shown modalles calling
Close dispose the form object. When the form is shown as a modal dialog,
though, Close hides the form and doesn't destroyed (disposed) it.
One is sure thing, though, Dispose always destroy. So bare this in mind when
you write your classes

--
HTH
Stoitcho Goutsev (100) [C# MVP]
"Willem van Rumpt" <no***********@no.thelandslide.spam.com> wrote in message
news:uK**************@TK2MSFTNGP12.phx.gbl...
Hi all,
coming from an unmanaged programming background, I took my time to
sort out the IDisposable and finalizer patterns. Just when I thought
I had it all conceptually neatly arranged, the "Close()" methods reared
their ugly (at least it would seem...)heads.

I was happily delving away in the .NET framework, investigating the
stream classes with the msdn and Lutz Roeder's .NET reflector, when I
stumbled upon the following:

(using BinaryReader as an example, though not the only "bad guy")
1) The MSDN : "This implementation of Close calls the Dispose method
passing a true value."
2) the Close() method in the BinaryReader is marked virtual
3) the "using" keyword will invoke the implemented IDisposable.Dispose()
on the expression you want to dispose

it looks to me like the "using" keyword in this case could be
potentially very dangerous. Nothing prevents me from descending from
BinaryReader, override the Close() method, and do some essential extra
work (marking a flag, log something, whatever), and everyone using my
class with the "using" keyword would have (at best) unnoticed side effects.
I can see the need for IDisposable, I can see the need for virtual
methods that will call Dispose on your behalf, but I don't get the need
for a "using" keyword for calling Dispose() for you, when (at least in
some cases) you might be short-circuiting things because you should've
called "Close()" (or whatever they choose to call it). The documentation
in the MSDN doesn't mention anywhere (that is, I couldn't find it...)
that you should use Close() instead of
Dispose() from the implemented interface.

Is (or should I mark) the "using" keyword "potentially dangerous"?

Thanks in advance,

Willem van Rumpt

Nov 16 '05 #3
Jon Skeet [C# MVP] wrote:
Willem van Rumpt <no***********@no.thelandslide.spam.com> wrote:

<snip>
Is (or should I mark) the "using" keyword "potentially dangerous"?

No - failing to use "using" is potentially dangerous.

If you want to write a class which doesn't implement Dispose
appropriately - i.e. if calling Dispose isn't enough to clean up the
unmanaged resources - that's fine. There's nothing to stop you from
writing badly behaved classes in .NET - but it *is* relatively easy to
write *well*-behaved classes instead.

I'm not talking unmanaged resources. I'm assuming that the Dispose()
part would be properly implemented, i.e. releasing all unmanaged
resources, BUT since the Close() method is virtual, it seems the class
can still work and have a function and a state which the Close() method
sets or invokes, which would not be invoked or set if using the "using"
keyword, even more, it has been explicitly marked "virtual" so
descendants can do their own thing before/after calling dispose.

From what you say, I think that I didn't grasp the meaning of
IDisposable correctly. Should I regard a "disposable" object as
"destroyed", not to be referenced again?.

Willem van Rumpt

Nov 16 '05 #4
Hi,

Just override Dispose(bool) and there put your code. Like this:

using System;
using System.IO;

namespace Test {

public class TestReader : BinaryReader {

public TestReader(Stream stream) : base(stream)
{
}

protected override void Dispose(bool disposing)
{
Console.WriteLine("Dispose called.");
base.Dispose(disposing);
}
}

public class Test {
[STAThread]
public static void Main()
{
TestReader testReader = new TestReader(new MemoryStream());
testReader.Close();
}
}
}

Sunny

In article <uK**************@TK2MSFTNGP12.phx.gbl>,
no***********@no.thelandslide.spam.com says...
Hi all,
coming from an unmanaged programming background, I took my time to
sort out the IDisposable and finalizer patterns. Just when I thought
I had it all conceptually neatly arranged, the "Close()" methods reared
their ugly (at least it would seem...)heads.

I was happily delving away in the .NET framework, investigating the
stream classes with the msdn and Lutz Roeder's .NET reflector, when I
stumbled upon the following:

(using BinaryReader as an example, though not the only "bad guy")
1) The MSDN : "This implementation of Close calls the Dispose method
passing a true value."
2) the Close() method in the BinaryReader is marked virtual
3) the "using" keyword will invoke the implemented IDisposable.Dispose()
on the expression you want to dispose

it looks to me like the "using" keyword in this case could be
potentially very dangerous. Nothing prevents me from descending from
BinaryReader, override the Close() method, and do some essential extra
work (marking a flag, log something, whatever), and everyone using my
class with the "using" keyword would have (at best) unnoticed side effects.

I can see the need for IDisposable, I can see the need for virtual
methods that will call Dispose on your behalf, but I don't get the need
for a "using" keyword for calling Dispose() for you, when (at least in
some cases) you might be short-circuiting things because you should've
called "Close()" (or whatever they choose to call it). The documentation
in the MSDN doesn't mention anywhere (that is, I couldn't find it...)
that you should use Close() instead of
Dispose() from the implemented interface.

Is (or should I mark) the "using" keyword "potentially dangerous"?

Thanks in advance,

Willem van Rumpt

Nov 16 '05 #5
Willem van Rumpt <no***********@no.thelandslide.spam.com> wrote:
If you want to write a class which doesn't implement Dispose
appropriately - i.e. if calling Dispose isn't enough to clean up the
unmanaged resources - that's fine. There's nothing to stop you from
writing badly behaved classes in .NET - but it *is* relatively easy to
write *well*-behaved classes instead.
I'm not talking unmanaged resources. I'm assuming that the Dispose()
part would be properly implemented, i.e. releasing all unmanaged
resources, BUT since the Close() method is virtual, it seems the class
can still work and have a function and a state which the Close() method
sets or invokes, which would not be invoked or set if using the "using"
keyword, even more, it has been explicitly marked "virtual" so
descendants can do their own thing before/after calling dispose.


For some classes, there may be things you can do with an object after
calling Close, but before calling Dispose.

It's interesting to note that Stream is rather different from
BinaryWriter - Dispose calls Close rather than the other way round.
From what you say, I think that I didn't grasp the meaning of
IDisposable correctly. Should I regard a "disposable" object as
"destroyed", not to be referenced again?.


When an object is disposed, it should usually either be ready to reuse
"from scratch" or shouldn't be reused at all - usually the latter.
Calling Dispose should be all that is required when one is finished
with an object, and it's very rare (IME) that it's good to call it
*before* one is finished with the object.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #6
LMFAO!!!

--
HTH

Kyril Magnos

"Richard" <Ri*****@discussions.microsoft.com> wrote in message
news:C4**********************************@microsof t.com...
|> Nothing prevents me from descending from
| > BinaryReader, override the Close() method, and do some essential extra
| > work (marking a flag, log something, whatever), and everyone using my
| > class with the "using" keyword would have (at best) unnoticed side
effects.
| >
|
| The IDisposable pattern wants you to do all of your extra work in the
overriden method aka "protected override void Dispose(bool disposing)". If
you put your extra work in there then the "using" keyword will work fine as
the keyword is going to call "void Dispose()" witch is implemented to call
your overriden "Dispose(true)" - hence doing your extra work...
|
| > Is (or should I mark) the "using" keyword "potentially dangerous"?
| >
|
| Don't forget that "using" is syntactically equivalent to try{}
finally{Dispose} so it's a good idea to use it. Actually I think the whole
IDispose thing is LAAAAMMMMMEEE! As a C++ guy I really really want a .NET
keyword "delete" that is defined as: immediately calls the object's
finalizer {if one exists} and then issues a GC.SuppressFinalizer() for the
object...
|
| But nooo nobody listens to me... Nope! I thought going into Iraq was a
dumb idea - all I wanted to do was confiscate Saudi Arabian oil and kick the
natives out into their endless beach. If we'd done that gas would be .10
per gallon, we would have flipped UBL the big time finger by confiscating
holy land, the Wahhabiist movement would have lost its funding, and we'd
have a HUGE base right next to Saddam Hussein while leaving HIM in token
power so that he can deal with the Iraqi people. But nooooo.... I get no
delete keyword and now I'm stuck with an estimated $30,000 per taxpayer bill
for a dumb headed plan to make the middle east safe for Israel....
|
| Nope nobody ever listens to me and that's why the world's a Flippin
mess...
|
|
|
|
|
Nov 16 '05 #7
Richard <Ri*****@discussions.microsoft.com> wrote:
Don't forget that "using" is syntactically equivalent to try{}
finally{Dispose} so it's a good idea to use it. Actually I think the
whole IDispose thing is LAAAAMMMMMEEE! As a C++ guy I really really
want a .NET keyword "delete" that is defined as: immediately calls
the object's finalizer {if one exists} and then issues a
GC.SuppressFinalizer() for the object...


That doesn't allow for situations where an object can be reused, of
course, which Dispose allows for in theory, even if it's rarely used.

You'd also still want another keyword in order to put the delete within
a try/finally block automatically, IMO.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: smitty mittlebaum | last post by:
I have a strange problem that has reared its ugly head in the last few weeks. I have the option "Compact on Close" (Tools, Options, General tab)...
19
by: Lauren Wilson | last post by:
A2K app: Question: is the flagged line (<<<) below necessary. If that line is needed, what effect does it have (if any) on the fact that the...
2
by: Paul LAURENT | last post by:
Hi everybody, I am using the STL "ofstream" class. I open a file using "ofstream" in update at the end mode ("ate"), I can read and write my...
4
by: Philipp Sumi | last post by:
Hello all I have a thread that performs some simple I/O within a loop that runs on a separate thread. I used the using keyword to ensure the...
5
by: lindanr | last post by:
In ASP.NET 2005 I have an onblur="window.close()" javascript event in the <body> tag. When I click on the window's scrollbar, the window closes. The...
4
by: R.A.M. | last post by:
Hello, (Sorry for my English...) I am learning C# and I have a question: is it good practice to use "using", for example: using (SqlConnection...
30
by: Pep | last post by:
Is it best to include the code "using namespace std;" in the source or should each keyword in the std namespace be qualified by the namespace tag,...
2
by: R.A.M. | last post by:
Hello, I have started larning C# and I have a question concerning "using (...)" keyword. For example: using (SqlConnection connection = new...
2
by: Steven W. Orr | last post by:
>From the tutorial, they said that the following construct will automatically close a previously open file descriptor: ------------------- #!...
0
by: tammygombez | last post by:
Hey fellow JavaFX developers, I'm currently working on a project that involves using a ComboBox in JavaFX, and I've run into a bit of an issue....
0
by: tammygombez | last post by:
Hey everyone! I've been researching gaming laptops lately, and I must say, they can get pretty expensive. However, I've come across some great...
0
by: concettolabs | last post by:
In today's business world, businesses are increasingly turning to PowerApps to develop custom business applications. PowerApps is a powerful tool...
0
better678
by: better678 | last post by:
Question: Discuss your understanding of the Java platform. Is the statement "Java is interpreted" correct? Answer: Java is an object-oriented...
0
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
0
by: CD Tom | last post by:
This only shows up in access runtime. When a user select a report from my report menu when they close the report they get a menu I've called Add-ins...
0
jalbright99669
by: jalbright99669 | last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
0
by: Matthew3360 | last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function. Here is my code. ...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.