By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,587 Members | 1,891 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,587 IT Pros & Developers. It's quick & easy.

How can I call base interface method?

P: n/a
jon
How can I call a base interface method?

class ThirdPartyClass :IDisposable { //I can not modify this class
void IDisposable.Dispose() {
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable {
void IDisposable.Dispose() {
Console.WriteLine( "MyClass Dispose" );
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}

Nov 17 '05 #1
Share this Question
Share on Google+
15 Replies


P: n/a
<jo*@martinsound.com> wrote:
How can I call a base interface method?

class ThirdPartyClass :IDisposable { //I can not modify this class
void IDisposable.Dispose() {
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable {
void IDisposable.Dispose() {
Console.WriteLine( "MyClass Dispose" );
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}


Good question - and to be honest, I don't *think* you can...

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

P: n/a


jo*@martinsound.com wrote:
How can I call a base interface method?

class ThirdPartyClass :IDisposable { //I can not modify this class
void IDisposable.Dispose() {
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable {
void IDisposable.Dispose() {
Console.WriteLine( "MyClass Dispose" );
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}


Hi,

Usually when a base class implements an IDisposable, it also implements
a "protected virtual void Dispose(bool disposing)" where the acctually
cleanup is done... (if it is done correctly).
and the Dispose() method calls it.

try to override it as follow:

class ThirdPartyClass :IDisposable
{ //I can not modify this class
void IDisposable.Dispose()
{
GC.SuppressFinalize(this);
Dispose(false);
}

protected virtual void Dispose(bool disposing)
{
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable
{
protected override void Dispose(bool disposing)
{
// Do your cleanup here
Console.WriteLine( "MyClass Dispose" );
base.Dispose(disposing);
}
}

if it doesn't implement a Dispose(bool disposing)

then you should do as you did, only:

class ThirdPartyClass :IDisposable
{ //I can not modify this class
void IDisposable.Dispose()
{
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable
{
void IDisposable.Dispose()
{
Console.WriteLine( "MyClass Dispose" );
base.Dispose(); // just call the base class implementation of the
Dispose.
}
}

Cheers,
Eyal.

Nov 17 '05 #3

P: n/a


jo*@martinsound.com wrote:
How can I call a base interface method?

class ThirdPartyClass :IDisposable { //I can not modify this class
void IDisposable.Dispose() {
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable {
void IDisposable.Dispose() {
Console.WriteLine( "MyClass Dispose" );
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}


Hi,

Usually when a base class implements an IDisposable, it also implements

a "protected virtual void Dispose(bool disposing)" where the acctually
cleanup is done... (if it is done correctly).
and the Dispose() method calls it.

try to override it as follow:

class ThirdPartyClass :IDisposable
{ //I can not modify this class
void IDisposable.Dispose()
{
GC.SuppressFinalize(this);
Dispose(false);
}

protected virtual void Dispose(bool disposing)
{
Console.WriteLine( "ThirdPartyClass Dispose" );
}

}

class MyClass :ThirdPartyClass, IDisposable
{
protected override void Dispose(bool disposing)
{
// Do your cleanup here
Console.WriteLine( "MyClass Dispose" );
base.Dispose(disposing);
}
}
if it doesn't implement a Dispose(bool disposing) and it implements the
IDisposable as: void IDisposable.Dispose(), then I guess you are
screwed... :(

Cheers,
Eyal.

Nov 17 '05 #4

P: n/a
Jon
My real problem involves a much more complicated class that uses
IBindingList.
I just used IDisposed in the posting as a simple example.

Like you say, I guess I am screwed.

Nov 17 '05 #5

P: n/a


Jon wrote:
My real problem involves a much more complicated class that uses
IBindingList.
I just used IDisposed in the posting as a simple example.

Like you say, I guess I am screwed.


HEY!!!! you are not screwed!!!!

I found you the answer!!!!

class MyClass :ThirdPartyClass, IDisposable
{
void IDisposable.Dispose()
{
// Do your cleanup here
Console.WriteLine( "MyClass Dispose" );

// Call the base.IDisposable.Dispose()
Type baseType = typeof(ThirdPartyClass);
InterfaceMapping map =
baseType.GetInterfaceMap(typeof(IDisposable));
map.TargetMethods[0].Invoke(this, new object[]{});
}
}
I just knew IDisposable has only one method, so I used
map.TargetMethods[0], you'll have to find your method in the
collection...

Good luck..

Eyal.

Nov 17 '05 #6

P: n/a


Eyal Safran wrote:
Jon wrote:
My real problem involves a much more complicated class that uses
IBindingList.
I just used IDisposed in the posting as a simple example.

Like you say, I guess I am screwed.


HEY!!!! you are not screwed!!!!

I found you the answer!!!!


or even more generic:

class MyClass :ThirdPartyClass, IDisposable
{
void IDisposable.Dispose()
{
// Do your cleanup here
Console.WriteLine( "MyClass Dispose" );

// Call the base.IDisposable.Dispose()
InterfaceMapping map =
GetType().BaseType.GetInterfaceMap(typeof(IDisposa ble));
map.TargetMethods[0].Invoke(this, new object[]{});
}
}

Eyal.

Nov 17 '05 #7

P: n/a
Jon,

The problem here has to do with multiple inheritence. As you know, C# only
supports single inheritence. Of course, you can implement multiple
interfaces. But, what does this really mean?

If you think about it, it means you can only inherit one implementation.
From this persepective, the IDisposable interface cannot have
implementation. By definition, it is an interface, not an implementation.
Hence, in your derived class, you can have the Dispose() method. But, you
don't get to inherit any base class functionality.

Now to the Crux of it... But ThirdPartyClass is a class, so why can't I
inherit its functionality. And the reason is, because the Dispose method in
this class is explicitly defined as an interface only. If the base class had
been defined as:

class ThirdPartyClass : IDisposable
{ //I can not modify this class
public void Dispose()
{
Console.WriteLine("ThirdPartyClass Dispose");
}
}

or better yet:

class ThirdPartyClass : IDisposable
{ //I can not modify this class
public virtual void Dispose()
{
Console.WriteLine("ThirdPartyClass Dispose");
}
}

then you would be able to inherit from this member. In the former case you
could use the "new" keyword, and in the later case "override" to implement
your method. For example, in the former case:

public override void Dispose()
{
Console.WriteLine("MyClass Dispose");
base.Dispose(); // now this works
}

or in the later case:

public new void Dispose()
{
Console.WriteLine("MyClass Dispose");
base.Dispose(); // now this works
}

You can use some trickery to get at the base type and get its hidden
implementation. But the purpose of the explicit interface definition was to
hide it and not allow this.

The trickery involves using reflection to get to the actual implementation
of the base class, and force the hidden method invocation. For example, as
suggested by Eyal Safrin:

public virtual void Dispose()
{
Console.WriteLine("MyClass Dispose");
InterfaceMapping map =
base.GetType().BaseType.GetInterfaceMap(typeof(IDi sposable));
map.TargetMethods[0].Invoke(this, new object[] {});
}

To fix this third party library once and for all, you might then create the
following wrapper class:

class ThirdPartyWrapper : ThirdPartyClass
{
public virtual void Dispose()
{
Console.WriteLine("Wrapper class");
InterfaceMapping map =
base.GetType().BaseType.GetInterfaceMap(typeof(IDi sposable));
map.TargetMethods[0].Invoke(this, new object[] {});
}
}

class MyClass : ThirdPartyWrapper, IDisposable
{
public override void Dispose()
{
Console.WriteLine("MyClass Dispose");
base.Dispose();
}
}

Then use this class for all internal usage.

Hope this helps...

--
Frisky

Intellectuals solve problems; geniuses prevent them. ~ Albert Einstein
<jo*@martinsound.com> wrote in message
news:11**********************@g14g2000cwa.googlegr oups.com...
How can I call a base interface method?

class ThirdPartyClass :IDisposable { //I can not modify this class
void IDisposable.Dispose() {
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable {
void IDisposable.Dispose() {
Console.WriteLine( "MyClass Dispose" );
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}

Nov 17 '05 #8

P: n/a
C# supports single inheritance of an implementation hierarchy and
multiple
inheritance of pure virtual classes aka interfaces in C#. Interfaces
provide the
same functionality as pure virtual classes in C++.

Regards,
Jeff
The problem here has to do with multiple inheritence. As you know, C#
only
supports single inheritence. Of course, you can implement multiple
interfaces. But, what does this really mean?

*** Sent via Developersdex http://www.developersdex.com ***
Nov 17 '05 #9

P: n/a
Since your implementation of IDisposable.Dispose() overwrite the original
entry of Dispose in the vtable there is no way to get back the pointer to
the original Dispose method.
If you find no other solution for your problem you can try with reflection.
<jo*@martinsound.com> schrieb im Newsbeitrag
news:11**********************@g14g2000cwa.googlegr oups.com...
How can I call a base interface method?

class ThirdPartyClass :IDisposable { //I can not modify this class
void IDisposable.Dispose() {
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable {
void IDisposable.Dispose() {
Console.WriteLine( "MyClass Dispose" );
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}

Nov 17 '05 #10

P: n/a
jo*@martinsound.com wrote:
How can I call a base interface method?

class ThirdPartyClass :IDisposable { //I can not modify this class
void IDisposable.Dispose() {
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable {
void IDisposable.Dispose() {
Console.WriteLine( "MyClass Dispose" );
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}


Not easily, as you can't call an explicit interface implementation via
base.Dispose (which is the point of the question, I suppose).

Anyhow, try casting MyClass to its ancestral type, then casting the
ancestral type to IDispose, as below. Note, though, that
DisposableAncestor.Dispose() calls MyClass.IDisposable.Dispose - which
makes sense, given that you could cast DisposableAncestor back to
MyClass ....

class MyClass :ThirdPartyClass, IDisposable
{
private bool Disposed;

void IDisposable.Dispose()
{
if (Disposed) //DisposableAncestor.Dispose() calls this method
return;
else
Disposed = true;

Console.WriteLine( "MyClass Dispose" );

IDisposable DisposableAncestor = (IDisposable)
((ThirdPartyClass) this);
DisposableAncestor.Dispose();
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}
--

www.midnightbeach.com
Nov 17 '05 #11

P: n/a
>
IDisposable DisposableAncestor = (IDisposable)
((ThirdPartyClass) this);
DisposableAncestor.Dispose();
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}


This won't work due to the reasons a gave in my post.
Nov 17 '05 #12

P: n/a
Cody,

The problem is that the method is not declared as virtual in the third party
class. Hence, the Dispose method is not virtual. (No VTable) Not the other
way around.

Frisky

"cody" <de********@gmx.de> wrote in message
news:uk**************@tk2msftngp13.phx.gbl...
Since your implementation of IDisposable.Dispose() overwrite the original
entry of Dispose in the vtable there is no way to get back the pointer to
the original Dispose method.
If you find no other solution for your problem you can try with
reflection.
<jo*@martinsound.com> schrieb im Newsbeitrag
news:11**********************@g14g2000cwa.googlegr oups.com...
How can I call a base interface method?

class ThirdPartyClass :IDisposable { //I can not modify this class
void IDisposable.Dispose() {
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable {
void IDisposable.Dispose() {
Console.WriteLine( "MyClass Dispose" );
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}


Nov 17 '05 #13

P: n/a
Implementation of an interface is not inheritence. There is nothing to
inherit. You are simply required to implement the specific signature as
required by the interface.

But, the problem is not that you are overwriting the VTable as cody
mentioned. There is not VTable entry for this item. That is because in the
third party class, the item was not marked as virtual. Ultimatley, this is
the problem. If the Dispose method in the third party class is marked as
virtual, then the method may be overwritten, and the base functionality may
be called. Try it, it works.

Since you can't change the third party class, you have to use a hack to get
around it.

"Jeff Louie" <je********@yahoo.com> wrote in message
news:OS****************@TK2MSFTNGP09.phx.gbl...
C# supports single inheritance of an implementation hierarchy and
multiple
inheritance of pure virtual classes aka interfaces in C#. Interfaces
provide the
same functionality as pure virtual classes in C++.

Regards,
Jeff
The problem here has to do with multiple inheritence. As you know, C#
only
supports single inheritence. Of course, you can implement multiple
interfaces. But, what does this really mean?

*** Sent via Developersdex http://www.developersdex.com ***

Nov 17 '05 #14

P: n/a
AFAIK, interface methods asre called through a vtable.
If they wouldn't, how would the compiler determine the address of the method
if I say test.Dispose() where test is of type IDisposible? Test could be any
class.
Under the hood, interface methods are declared as sealed *and* virtual.

"Frisky" <Fr***********@NorthPole.Net> schrieb im Newsbeitrag
news:uI**************@TK2MSFTNGP09.phx.gbl...
Cody,

The problem is that the method is not declared as virtual in the third party class. Hence, the Dispose method is not virtual. (No VTable) Not the other
way around.

Frisky

"cody" <de********@gmx.de> wrote in message
news:uk**************@tk2msftngp13.phx.gbl...
Since your implementation of IDisposable.Dispose() overwrite the original entry of Dispose in the vtable there is no way to get back the pointer to the original Dispose method.
If you find no other solution for your problem you can try with
reflection.
<jo*@martinsound.com> schrieb im Newsbeitrag
news:11**********************@g14g2000cwa.googlegr oups.com...
How can I call a base interface method?

class ThirdPartyClass :IDisposable { //I can not modify this class
void IDisposable.Dispose() {
Console.WriteLine( "ThirdPartyClass Dispose" );
}
}

class MyClass :ThirdPartyClass, IDisposable {
void IDisposable.Dispose() {
Console.WriteLine( "MyClass Dispose" );
//base.IDisposable.Dispose(); //How can I do this !!!!
}
}



Nov 17 '05 #15

P: n/a
Cody,

Ok, you got me on a technicality. Internally, yeah, the compiler does some
wierd stuff to make things work.

And, I forgot to say that this was caused by the fact that the method is an
explicit interface method.

But, generically, the VTable is used to lookup virtual functions for a
class. Not an interface. (The "V" in VTable stands for virtual.)

Interfaces do not have virtual methods. Classes do. Interfaces do not have
implementations. Classes do.

In your example, you interchange interface and class; yet they are
distinctly different. (As shown above.)

Yes, when you implement a class, the interface methods in the class are
marked virtual, but final. Hence, you can "new" them, but not override them.
True virtual functions are those that may be overriden. The resaon the are
sealed (marked final) is because there is no inheritence. Unless of course
you implement them in a class, and then inherit from the class. But, then,
unless you mark the method virtual, you still can only new them.

However, in the example, the problem is that the method was declared as an
explicit interface. Internally this is seen as an override, but, it is an
override of an interface which has no implementation. Hence, you get no
inheritence. And, the compiler will not let you call the base method either,
because an interface does not have implementation.

As I pointed out in my other post, the method needs to be declared as a
regular class method to provide implementation inheritence. Since it is
defined explicitly as an interface (no implementation), the compiler won't
let you call the (as far as it is concerned) non-existent implementation.
Hence, you must resort to hack (reflection) to get at the implementation.

"cody" <de********@gmx.de> wrote in message
news:uM**************@TK2MSFTNGP10.phx.gbl...
AFAIK, interface methods asre called through a vtable.
If they wouldn't, how would the compiler determine the address of the
method
if I say test.Dispose() where test is of type IDisposible? Test could be
any
class.
Under the hood, interface methods are declared as sealed *and* virtual.

"Frisky" <Fr***********@NorthPole.Net> schrieb im Newsbeitrag
news:uI**************@TK2MSFTNGP09.phx.gbl...
Cody,

The problem is that the method is not declared as virtual in the third

party
class. Hence, the Dispose method is not virtual. (No VTable) Not the
other
way around.

Frisky

"cody" <de********@gmx.de> wrote in message
news:uk**************@tk2msftngp13.phx.gbl...
> Since your implementation of IDisposable.Dispose() overwrite the original > entry of Dispose in the vtable there is no way to get back the pointer to > the original Dispose method.
> If you find no other solution for your problem you can try with
> reflection.
>
>
> <jo*@martinsound.com> schrieb im Newsbeitrag
> news:11**********************@g14g2000cwa.googlegr oups.com...
>> How can I call a base interface method?
>>
>> class ThirdPartyClass :IDisposable { //I can not modify this class
>> void IDisposable.Dispose() {
>> Console.WriteLine( "ThirdPartyClass Dispose" );
>> }
>> }
>>
>> class MyClass :ThirdPartyClass, IDisposable {
>> void IDisposable.Dispose() {
>> Console.WriteLine( "MyClass Dispose" );
>> //base.IDisposable.Dispose(); //How can I do this !!!!
>> }
>> }
>>
>
>



Nov 17 '05 #16

This discussion thread is closed

Replies have been disabled for this discussion.