How to implement an interface explicitly with a virtual method?
Asked Answered
F

5

5

I can't do this

interface InterfaceA
{
    void MethodA();
}

class ClassA : InterfaceA
{
    virtual void InterfaceA.MethodA()
    // Error: The modifier 'virtual' is not valid for this item
    {
    }
}

Where the following works

class ClassA : InterfaceA
{
    public virtual void MethodA()
    {
    }
}

Why? How to circumvent this?

Federico answered 26/7, 2010 at 16:57 Comment(3)
Why do you want to circumvent it? What benefit does that add?Success
@Eric It will save me some typingFederico
How does not being allowed to mark an explicit interface method as being virtual cause you more typing?Success
S
8

I think this is because when a member is explicitly implemented, it cannot be accessed through a class instance, but only through an instance of the interface.

So making something 'virtual' really does not make sense in this case, since virtual means that you intend to override it in an inherited class. Implementing an interface explicitly and making it virtual would be contradictory. Which also may be why the compiler disallows this.

To work around it I think csharptest.net's or Philip's answer sounds like it would do the trick

Scotfree answered 26/7, 2010 at 17:2 Comment(1)
Good explanation as to why it doesn't make sense to want that.Circinate
H
3

According to C# language spec:

It is a compile-time error for an explicit interface member implementation to include access modifiers, and it is a compile-time error to include the modifiers abstract, virtual, override, or static.

You can "get around" it only by calling your virtual method from the explicit interface implementation.

Hithermost answered 26/7, 2010 at 17:4 Comment(0)
C
3

You have to do something like this:

interface InterfaceA
{
    void MethodA();
}

class ClassA : InterfaceA
{
    void InterfaceA.MethodA()
    { MethodB(); }

    protected virtual void MethodB()
    { 
    }
}

Often this is a superior approach anyway as the internal method may change signature without changing the interface. Take a more real-word example:

interface IOrderDetails
{
    void PlaceOrder();
}

//Sometime later you extend with:
interface IOrderDetails2 : IOrderDetails
{
    void PlaceOrder(IUser user);
}

//Implementation
class Order : IOrderDetails, IOrderDetails2
{
    static readonly IUser AnonUser;

    void IOrderDetails.PlaceOrder()
    { OnPlaceOrder(AnonUser); }
    void IOrderDetails2.PlaceOrder(IUser user)
    { OnPlaceOrder(user); }

    protected virtual void OnPlaceOrder(IUser user)
    { 
    }
}

Here you can see as the IOrderDetails2 was added we can safely refactor the existing virtual method (thus generating compile-time errors for derivations). Additionally this often allows you to provide common functionality, logging, and exception handling in the base implementation class...

Cason answered 26/7, 2010 at 17:15 Comment(0)
M
0

You cannot use the virtual modifier with the static, abstract, private or override modifiers. default modifier is private

Malleable answered 26/7, 2010 at 17:0 Comment(1)
Interestingly for explicit implementations the modifier is public, though it can only be accessed if the instance is cast to the respective interface type.Federico

© 2022 - 2024 — McMap. All rights reserved.