473,327 Members | 2,112 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

How can I call base interface method?

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
15 12738
<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


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


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
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


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


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
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
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
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
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
>
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

39
by: Randell D. | last post by:
Folks, I'm sure this can be done legally, and not thru tricks of the trade - I hope someone can help. I'm writing a 'tool' (a function) which can be used generically in any of my projects. ...
9
by: keith | last post by:
I created a class libery which has name space Assembly and class Assembly and compiled it. Then created a C# project and called a method in the external class e.g. Assembly dll;...
24
by: Jazper | last post by:
hi i have this problem. i made a class deverted by CRootItem with implementation of IDisposable-Interface. i made a test-funktion to test my Dispose-Method.... but when set a breakpoint in my...
4
by: Ray Dukes | last post by:
What I am looking to do is map the implementation of interface properties and functions to an inherited method of the base class. Please see below. ...
2
by: Oenone | last post by:
I could use a little advice to help prevent me making a possible mess of a project. :) In VB6, I once created a project that exposed a public interface class. I then Implemented this in various...
9
by: Sean Kirkpatrick | last post by:
To my eye, there doesn't seem to be a whole lot of difference between the two of them from a functional point of view. Can someone give me a good explanation of why one vs the other? Sean
2
by: Kevin Frey | last post by:
In a derived class I am trying to redefine the implementation of a interface method defined in a base class - the base class interface method was not declared virtual. I have yet to actually...
4
by: archimed7592 | last post by:
Hi. for example i have base class A and dirved class B: struct A { virtual void f() { std::cout << "A::f()" << std::endl; } }; struct B : public A {
3
by: Julie | last post by:
Here's the scenario (public attributes, etc. omitted for brevity): class Base { } class Derived : Base { }
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.