Using interface and dispose

T

Tony

Hello!

I know that the block of code below is the same as using the using clause.
I must have this kind of text because the question is about the statement
((IDisposable)reader).Dispose();

Now to my question:
If I use this statement ((IDisposable)reader).Dispose();
or reader.Dispose();
must mean exactly the same thing.
It's the method Dispose in the TextReader class that is called here because
it's not virtual.


{
TextReader reader = new StreamReader("some filename";
try
{
string line;
while((line = reader.ReadLine()) != null)
{
Console.WrileLine(line);
}
}
finally
{
if (reader != null)
{
((IDisposable)redaer).Dispose();
}
}
}

//Tony
 
J

Jon Skeet [C# MVP]

I know that the block of code below is the same as using the using clause.
I must have this kind of text because the question is about the statement
((IDisposable)reader).Dispose();

Now to my question:
If I use this statement ((IDisposable)reader).Dispose();
or reader.Dispose();
must mean exactly the same thing.

In this particular case, yes. With other types, no.
It's the method Dispose in the TextReader class that is called here because
it's not virtual.

It's not the virtual side of things that's important. It's the fact
that some classes will implement IDisposable using explicit interface
implementation. At that point, you have to cast the reference to
IDisposable in order to call Dispose, because it's not visible through
an expression of the class type.

Jon
 
T

Tony

Hello!

So which Dispose in which class is called.
I far as I understand it must be in the TextReader class.

//Tony
 
J

Jon Skeet [C# MVP]

So which Dispose in which class is called.
I far as I understand it must be in the TextReader class.

In this particular case, yes.

However, suppose you had:

public class OddTextReader : TextReader, IDisposable
{
// Abstract methods etc filled in

void IDisposable.Dispose()
{
// Some stuff here
}
}

then:

using (TextReader reader = new OddTextReader())
{
...
}

would call the OddTextReader's explicit interface implementation of
Dispose.

Jon
 
T

Tony

Hello!

I tested you example and it was the Dispose of OddTextReader that was
called.
I would understand it if this Dispose had been declared as virtual in
TextReader.
Here is the same as your example. Here I get the same strange result that I
don't understand.
When test is called as an interface it's test in MyDerived that is called in
spite of
having this method Test as public void Test(...) not using virtual
If I replace ITest with MyBase then Test in the MyBase is called which is
correct and understandable.

So can you explain why Test in MyDerived class is called. It should be Test
in MyBase according to my knowledge.

ITest test = new MyDerived();
test.Test();

interface ITest
{ void Test() }

public class MyBase
{ public void Test() {} }

public class MyDerived : MyBase, ITest
{ public void Test() {} }

//Tony
 
J

Jon Skeet [C# MVP]

So can you explain why Test in MyDerived class is called. It should be Test
in MyBase according to my knowledge.

Well, you're reimplementing ITest (although note that you're doing it
in a different way to my example - you're not using explicit interface
implementation).

Sections 13.4.5 and 13.4.6 of the C# 3 spec go into the details.

Jon
 
T

Tony

Hello!

Your example work the same even if I implement this Dispose implicit meaning
that it's the Dispose in OddTextReader that is called.
The reason for this accoring to my knowledge is that
the call to Dispose is beibng made as a being a Disposable.

public class OddTextReader : TextReader, IDisposable
{
// Abstract methods etc filled in

void IDisposable.Dispose()
{
// Some stuff here
}
}

then:

using (TextReader reader = new OddTextReader())
{
((IDisposable)reader).Dispose();
...
}

would call the OddTextReader's explicit interface implementation of
Dispose.

//Tony
 
J

Jon Skeet [C# MVP]

Your example work the same even if I implement this Dispose implicit meaning
that it's the Dispose in OddTextReader that is called.

Yes - the results were the same (in this case), but I was just
pointing out the difference in case you hadn't spotted it.
The reason for this accoring to my knowledge is that
the call to Dispose is beibng made as a being a Disposable.

Yes.

Jon
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top