about the using clause

  • Thread starter Thread starter Tony Johansson
  • Start date Start date
T

Tony Johansson

Hello!

Below is a snipped from a using clause.
Here I have a TextReader variable that is references a StreamReader object.
Just before this using block is finished the dispose method will be called
because the IDisposable interface is implemented.
I wonder in what class will dispose be called is it the dispose method in
class TextReader or the dispose in class StreamReader. Tell me also why is
it TextReader or StreamReader.
If I look in the documentation for dispose for class StreamReader it says
"Releases all resources used by the TextReader" object. I would say that the
dispose for class StreamReader would release all resources used by
StreamReader instead of TextReader.

I looked at documentation for the dispose method in TextReader and it was
not declared to be virtual so polymorfism will not be used.

using (TextReader reader = new StreamReader(fullPathname))
{
string line;
while ((line = reader.ReadLine()) != null)
{
source.Text += line + "\n";
}
}

//Tony
 
Tony Johansson said:
Below is a snipped from a using clause.
Here I have a TextReader variable that is references a StreamReader object.
Just before this using block is finished the dispose method will be called
because the IDisposable interface is implemented.
I wonder in what class will dispose be called is it the dispose method in
class TextReader or the dispose in class StreamReader. Tell me also why is
it TextReader or StreamReader.

<snip>

TextReader.Dispose() will be called, which will in turn call the
virtual Dispose(boolean) method.
 
Tony,

Well, StreamReader inherits the Dispose method from the TextReader,
which is why the documentation points to the TextReader documentation (if
you look at the list of Dispose overloads, next to the one without
parameters, it says "inherited from textreader").

However, the StreamReader implements the Dispose method which has
parameters, which is called by the TextReader implementation of Dispose. It
calls the implementation on the derived class.

This is the typical pattern for the implementation of IDisposable.

As for your example, all the resources that are in use by the
StreamReader which need to be disposed of, will.
 
Nicholas Paldino said:
Tony,

Well, StreamReader inherits the Dispose method from the TextReader,
which is why the documentation points to the TextReader documentation (if
you look at the list of Dispose overloads, next to the one without
parameters, it says "inherited from textreader").

However, the StreamReader implements the Dispose method which has
parameters, which is called by the TextReader implementation of Dispose.
It calls the implementation on the derived class.

This is the typical pattern for the implementation of IDisposable.

As for your example, all the resources that are in use by the
StreamReader which need to be disposed of, will.

Note also that Dispose, being an interface method, is always called
polymorphically (actually virtually, except if the compile-time type of the
variable was a sealed class or perhaps if the object was constructed
locally, in either case the compiler knows the exact type of the object).
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Tony Johansson said:
Hello!

Below is a snipped from a using clause.
Here I have a TextReader variable that is references a StreamReader
object.
Just before this using block is finished the dispose method will be
called because the IDisposable interface is implemented.
I wonder in what class will dispose be called is it the dispose method in
class TextReader or the dispose in class StreamReader. Tell me also why
is it TextReader or StreamReader.
If I look in the documentation for dispose for class StreamReader it says
"Releases all resources used by the TextReader" object. I would say that
the dispose for class StreamReader would release all resources used by
StreamReader instead of TextReader.

I looked at documentation for the dispose method in TextReader and it was
not declared to be virtual so polymorfism will not be used.

using (TextReader reader = new StreamReader(fullPathname))
{
string line;
while ((line = reader.ReadLine()) != null)
{
source.Text += line + "\n";
}
}

//Tony
 
Note also that Dispose, being an interface method, is always called
polymorphically (actually virtually, except if the compile-time type of the
variable was a sealed class or perhaps if the object was constructed
locally, in either case the compiler knows the exact type of the object).

Or if the implementation in the declared class is sealed, presumably...
 
Add to that list when the variable type is a structure which implicitly
implements the IDisposable interface. In that case, the call is not
virtual.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
Tony,

Well, StreamReader inherits the Dispose method from the TextReader,
which is why the documentation points to the TextReader documentation (if
you look at the list of Dispose overloads, next to the one without
parameters, it says "inherited from textreader").

However, the StreamReader implements the Dispose method which has
parameters, which is called by the TextReader implementation of Dispose.
It calls the implementation on the derived class.

This is the typical pattern for the implementation of IDisposable.

As for your example, all the resources that are in use by the
StreamReader which need to be disposed of, will.

Note also that Dispose, being an interface method, is always called
polymorphically (actually virtually, except if the compile-time type of
the variable was a sealed class or perhaps if the object was constructed
locally, in either case the compiler knows the exact type of the object).
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Tony Johansson said:
Hello!

Below is a snipped from a using clause.
Here I have a TextReader variable that is references a StreamReader
object.
Just before this using block is finished the dispose method will be
called because the IDisposable interface is implemented.
I wonder in what class will dispose be called is it the dispose method
in class TextReader or the dispose in class StreamReader. Tell me also
why is it TextReader or StreamReader.
If I look in the documentation for dispose for class StreamReader it
says "Releases all resources used by the TextReader" object. I would say
that the dispose for class StreamReader would release all resources used
by StreamReader instead of TextReader.

I looked at documentation for the dispose method in TextReader and it
was not declared to be virtual so polymorfism will not be used.

using (TextReader reader = new StreamReader(fullPathname))
{
string line;
while ((line = reader.ReadLine()) != null)
{
source.Text += line + "\n";
}
}

//Tony
 
Nicholas Paldino said:
Add to that list when the variable type is a structure which implicitly
implements the IDisposable interface. In that case, the call is not
virtual.

Only if the call is made through a variable of value type, if it is boxed
then it may still be a virtual call. Furthermore, I already covered that
case as "the compile-time type of the variable was a sealed class", as all
value types are sealed.
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ben Voigt said:
Nicholas Paldino said:
Tony,

Well, StreamReader inherits the Dispose method from the TextReader,
which is why the documentation points to the TextReader documentation
(if you look at the list of Dispose overloads, next to the one without
parameters, it says "inherited from textreader").

However, the StreamReader implements the Dispose method which has
parameters, which is called by the TextReader implementation of Dispose.
It calls the implementation on the derived class.

This is the typical pattern for the implementation of IDisposable.

As for your example, all the resources that are in use by the
StreamReader which need to be disposed of, will.

Note also that Dispose, being an interface method, is always called
polymorphically (actually virtually, except if the compile-time type of
the variable was a sealed class or perhaps if the object was constructed
locally, in either case the compiler knows the exact type of the object).
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hello!

Below is a snipped from a using clause.
Here I have a TextReader variable that is references a StreamReader
object.
Just before this using block is finished the dispose method will be
called because the IDisposable interface is implemented.
I wonder in what class will dispose be called is it the dispose method
in class TextReader or the dispose in class StreamReader. Tell me also
why is it TextReader or StreamReader.
If I look in the documentation for dispose for class StreamReader it
says "Releases all resources used by the TextReader" object. I would
say that the dispose for class StreamReader would release all resources
used by StreamReader instead of TextReader.

I looked at documentation for the dispose method in TextReader and it
was not declared to be virtual so polymorfism will not be used.

using (TextReader reader = new StreamReader(fullPathname))
{
string line;
while ((line = reader.ReadLine()) != null)
{
source.Text += line + "\n";
}
}

//Tony
 
Jon Skeet said:
Or if the implementation in the declared class is sealed, presumably...

Can you seal an interface implementation so that a derived class cannot
re-implement the interface? I thought calls through interfaces always
result in using the most-derived implementation.

I guess maybe it's possible to be calling the method through the class
instead of the interface, in which case the more-derived implementation
might not be found. I'd think that "using" is defined in terms of
IDisposable though, not "the method named Dispose in the given class".
 
Ben Voigt said:
Can you seal an interface implementation so that a derived class cannot
re-implement the interface?

Absolutely. Indeed, most implementations of IDisposable (e.g. Stream)
do this, introducing a virtual Dispose(bool disposing) method.

That's the only use for "sealed" on a method, IIRC.
I thought calls through interfaces always
result in using the most-derived implementation.

I guess maybe it's possible to be calling the method through the class
instead of the interface, in which case the more-derived implementation
might not be found. I'd think that "using" is defined in terms of
IDisposable though, not "the method named Dispose in the given class".

Yes. (foreach is slightly more interesting though - you don't actually
have to implement IEnumerable or IEnumerable<T> to get it to work...)
 
Back
Top