473,289 Members | 1,829 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,289 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 12734
<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: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
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: 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...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...

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.