Overriding interface members


S

Sebastian

Hi,

I'm confronted with a problem that seems not to be solvable. In
general: How can I override an interface member of my base class and
call the overridden method from my derived class?

This is my class:
class RemoteXmlDataSource : System.Web.UI.WebControls.XmlDataSource

And I want to override
DataSourceView System.Web.UI.IDataSource.GetView(string viewName)
but I want to make a call to the overridden method right after my
stuff.

Declaring the member with override, I get the message
The modifier 'override' is not valid for this item

When trying to access the "overridden" member with
(IDataSource)base).GetView(viewName), I get the message
Use of keyword 'base' is not valid in this context

Ok I understand, my interface member completely replaces the member
from the base class. Is there any way to do this even though?
I tried something like
((IDataSource)(XmlDataSource)this).GetView(viewName)
but that just calls my new member :)

That makes deriving much harder than just overriding a virtual method
and calling base.X()... But I hope I just did not fully understand ;)

Kind regards, Sebastian
 
Ad

Advertisements

I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Sebastian said:
Hi,

I'm confronted with a problem that seems not to be solvable. In
general: How can I override an interface member of my base class and
call the overridden method from my derived class?

This is my class:
class RemoteXmlDataSource : System.Web.UI.WebControls.XmlDataSource

And I want to override
DataSourceView System.Web.UI.IDataSource.GetView(string viewName)
but I want to make a call to the overridden method right after my
stuff.

Declaring the member with override, I get the message
The modifier 'override' is not valid for this item

Did you declare the base as public virtual?

See if this code helps you:

class Program
{
static void Main(string[] args)
{
B b = new C();
b.M();

II i = b;
i.M();
Console.Read();
}
}

class B : II
{
public virtual void M() { Console.WriteLine("B.M"); }
}
class C : B
{
public override void M()
{
Console.WriteLine("C.M");
}
}

public interface II
{
void M();
}
 
B

Ben Voigt [C++ MVP]

Ignacio Machin ( .NET/ C# MVP ) said:
Hi,

Sebastian said:
Hi,

I'm confronted with a problem that seems not to be solvable. In
general: How can I override an interface member of my base class and
call the overridden method from my derived class?

This is my class:
class RemoteXmlDataSource : System.Web.UI.WebControls.XmlDataSource

And I want to override
DataSourceView System.Web.UI.IDataSource.GetView(string viewName)
but I want to make a call to the overridden method right after my
stuff.

Declaring the member with override, I get the message
The modifier 'override' is not valid for this item

Did you declare the base as public virtual?

See if this code helps you:

class Program
{
static void Main(string[] args)
{
B b = new C();
b.M();

II i = b;
i.M();
Console.Read();
}
}

class B : II
{
public virtual void M() { Console.WriteLine("B.M"); }

I assume that the base class method implements an interface, but doesn't use
the virtual keyword (that might make it sealed).
 
S

Sebastian

It turns out that declaring explicit interface implementations as
virtual is not possible - only implicit interface implementation
support that. Seems to be a limitation of the C# language. Or is there
a way I do not see?

Look at this snippet:

interface IFace {
string iFaceMethod();
}

public class BaseClass : IFace {
// works (implicit interface implementation)
public virtual string iFaceMethod() { return "BaseClass public
virtual string iFaceMethod()"; }

// works (explicit interface implementation - obove method won't be
anymore an implicit interface implementation)
string IFace.iFaceMethod() { return "BaseClass string
IFace.iFaceMethod()"; }

// The modifier 'public' is not valid for this item
// The modifier 'virtual' is not valid for this item
//public virtual string IFace.iFaceMethod() { }
}

public class DerivedClass : BaseClass, IFace {

// works
public override string iFaceMethod() {
// Use of keyword 'base' is not valid in this context
//return ((IFace)base).iFaceMethod();

// works
//return base.iFaceMethod(); // calls BaseClass public virtual
string iFaceMethod()

return "DerivedClass public override string iFaceMethod()";
}

// works, but would definitely hide base.iFaceMethod
string IFace.iFaceMethod() {
// Use of keyword 'base' is not valid in this context
//return ((IFace)base).iFaceMethod();

// works
//return base.iFaceMethod(); // calls BaseClass public virtual
string iFaceMethod()

// works, but leads to infinite recursion
//return ((IFace)this).iFaceMethod();

return "DerivedClass string IFace.iFaceMethod()";
}

// The modifier 'public' is not valid for this item
// The modifier 'override' is not valid for this item
//public override string IFace.iFaceMethod() { }
}

Kind regards, Sebastian
 
B

Ben Voigt [C++ MVP]

Sebastian said:
It turns out that declaring explicit interface implementations as
virtual is not possible - only implicit interface implementation
support that. Seems to be a limitation of the C# language. Or is there
a way I do not see?

No, you're right. explicit interface implementations are always private
(therefore can't be virtual), and implicit implementations are always
public. There's no way to get anything in-between.
 
S

Sebastian

No, you're right. explicit interface implementations are always private
(therefore can't be virtual), and implicit implementations are always
public. There's no way to get anything in-between.

Why are implicit implementations always public and explicit interface
implementations are always private?
Is there any logical explanation for that? For me, it sounds just
stupid. When implementing two methods from different interfaces that
have the same name, the methods can never be overridden because they
have to be explicit.

Kind regards, Sebastian
 
Ad

Advertisements

J

Jon Skeet [C# MVP]

Why are implicit implementations always public and explicit interface
implementations are always private?
Is there any logical explanation for that? For me, it sounds just
stupid. When implementing two methods from different interfaces that
have the same name, the methods can never be overridden because they
have to be explicit.

I think I've got a solution, actually. You just need to reimplement
the interface. You don't specify that you're overriding it, just that
you're implementing it. Here's some code to demonstrate what I mean -
if it doesn't do what you want it to, it would be good to know exactly
what's still missing. Note that you have to redeclare that you're
implementing IDisposable in the derived class.

using System;

public class Base : IDisposable
{
void IDisposable.Dispose()
{
Console.WriteLine ("Base");
}
}

public class Derived : Base, IDisposable
{
void IDisposable.Dispose()
{
Console.WriteLine ("Derived");
}
}

public class Test
{
static void Main()
{
IDisposable a = new Base();
IDisposable b = new Derived();

a.Dispose();
b.Dispose();
}
}

Jon
 
M

Marc Gravell

This is a feature of the C# compiler (I believe you have other options
in VB for instance). You can, however, simply write a protected inner
method for each, and forward from the explicit interface call - i.e.

void ISomeInterface.SomeMethod() {SomeInterfaceSomeMethod();}
void IOtherInterface.SomeMethod() {OtherInterfaceSomeMethod();}
protected virtual void SomeInterfaceSomeMethod() {...}
protected virtual void OtherInterfaceSomeMethod() {...}

Marc
 
S

Sebastian

I think I've got a solution, actually. You just need to reimplement
the interface. You don't specify that you're overriding it, just that
you're implementing it.

In that case, you cannot call the overridden method, as it would be
possible in virtual methods (base keyword). I tried to show this in my
last code example - maybe it's hard legible because of the line
wraps...

This is a feature of the C# compiler
LOL In my oppinion it's a defect :D
simply write a protected inner
method for each, and forward from the explicit interface call
Yes this would work. But this is not possible with existing (i.e.
built in .NET) classes that do not implement that way...

Sebastian
 
J

Jon Skeet [C# MVP]

In that case, you cannot call the overridden method, as it would be
possible in virtual methods (base keyword). I tried to show this in my
last code example - maybe it's hard legible because of the line
wraps...

That's true. It can be done with reflection, but I agree that's pretty
grim:

void IDisposable.Dispose()
{
Console.WriteLine ("Derived");
InterfaceMapping mapping =
typeof(Base).GetInterfaceMap(typeof(IDisposable));
MethodInfo method = mapping.TargetMethods[0];
method.Invoke(this, null);
}

(I only used 0 blindly because IDisposable has only one member.)

Jon
 
Ad

Advertisements

S

Sebastian

That's true. It can be done with reflection, but I agree that's pretty
Many thanks for your workaround!

Nevertheless, I can't imagine that this was the intention by the C#
language developers...

Kind regards, Sebastian
 
Ad

Advertisements


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