Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to force an interface implementation to be virtual in C#?

I ran into a problem today trying to override an implementation of an interface method which had not been declared virtual.

In this case I'm not able to change the interface or the base implementation and have to try something else, but I was wondering if there was a way to force a class to implement an interface using virtual methods.

Example:

interface IBuilder<T>
{
    // Already implicitly virtual
    /*virtual*/ T Build();
}

// This is a class written by someone else
class SimpleBuilder: IBuilder<SomeObject>
{
    // I would like to force this to be virtual
    public SomeObject Build() { return new SomeObject(); }
}

// This is the class I am writing.
class CustomBuilder: SimpleBuilder
{
    public /*override*/ SomeObject Build()
    {
        var obj = base.Build();
        obj.ModifyInSomeWay();
        return obj;
    }
}

Edit: CustomBuilder is intended to be used with MEF so I am deriving from SimpleBuilder in order for MEF to resolve the correct type. I've tried explicitly implementing the interface and not deriving from SimpleBuilder at all but then MEF doesn't pick up the right type.

The interface and base class in question are in a shared module created by another developer so it looks like I will have to get them to change their base class anyway.

like image 830
andrews_nz Avatar asked Sep 18 '25 20:09

andrews_nz


2 Answers

No there isn't, in your example you're implicitly implementing the interface. If your class is meant to be subclassed and a method overridden it is up to the developer to ensure that the method is marked as virtual.

There is no way to force implementations of interface methods to be overrideable in code, only conventions within a development team could ensure this (eg all interfaces should be explicitly implemented, all interface implementations should be marked as virtual etc).

In this specific example you could insert an abstract class into the hierarchy:

abstract class VirtualBuilder<T> : IBuilder<T>
{
  abstract T Build();
}

But this isn't suitable in the generic case, since you lose having the benefits of interfaces and 'force' all concrete classes to only implement one interface.

like image 182
Rich O'Kelly Avatar answered Sep 20 '25 11:09

Rich O'Kelly


Not directly, no.

You could "force" it by providing your own base class and requiring that users derive from it:

abstract class BuilderBase<T> : IBuilder<T>
{
    public abstract T Build();
}

But this has serious problems too becase

  1. it does not immediately stop anyone from implementing the interface directly (although you could e.g. require incoming parameters to be BuilderBase<T> instead of simply IBuilder<T>, or even make IBuilder<T> internal and hide it in another assembly)
  2. it forces implementers of the interface to give up their choice for the single base class, for which they might hate you
like image 22
Jon Avatar answered Sep 20 '25 11:09

Jon