When browsing ASP.NET MVC source code in codeplex, I found it is common to have a class explicitly implementing interface. The explicitly implemented method/property then in
sample for reason 1:
public interface IFoo
{
void method1();
void method2();
}
public class Foo : IFoo
{
// you can't declare explicit implemented method as public
void IFoo.method1()
{
}
public void method2()
{
}
private void test()
{
var foo = new Foo();
foo.method1(); //ERROR: not accessible because foo is object instance
method1(); //ERROR: not accessible because foo is object instance
foo.method2(); //OK
method2(); //OK
IFoo ifoo = new Foo();
ifoo.method1(); //OK, because ifoo declared as interface
ifoo.method2(); //OK
}
}
If a class implements IFoo.Bar
explicitly, and a derived class needs IFoo.Bar
to do something different, there will be no way for the derived class to call the base-class implementation of that method. A derived class which does not re-implement IFoo.Bar
could call the base-class implementation via ((IFoo)this).Bar()
, but if the derived class re-implements IFoo.Bar
(as it would have to in order to change its behavior) the aforementioned call would go to the derived-class re-implementation, rather than the base-class implementation. Even ((IFoo)(BaseType)this).bar
wouldn't help, since casting a reference to an interface type will discard any information about the type of the reference (as opposed to the type of the instance instance) that was cast.
Having an explicit interface implementation do nothing but call a protected method avoids this problem, since a derived class can change the behavior of the interface method by overriding the virtual method, while retaining the ability to call the base implementation as it sees fit. IMHO, C# should have had an explicit interface implementation produce a virtual method with a CLS-compliant name, so someone writing in C# a derivative of a class that explicitly implemented IFoo.Bar
could say override void IFoo.Bar
, and someone writing in some other language could say, e.g. Overrides Sub Explicit_IFoo_Bar()
; since any derived class can re-implement IFoo.Bar
, and since any derived class which doesn't re-implement IFoo.Bar
can call it on itself, I don't see that there's any useful purpose to having the explicit implementation be sealed.
Incidentally, in vb.net, the normal pattern would simply be Protected Overridable Sub IFoo_Bar() Implements IFoo.Bar
, without need for a separate virtual method.
Well, not specific to MVC, but this approach allows you to keep the core public API clean. It is also useful if there is ever a risk of different interfaces / etc having the same name & signature, but different meaning. In reality this is rare.
It also allows you to provide an implementation where you want the return type to change in subclasses:
(ICloneable
chosen for simplicity - don't get hung up on the fact that it is a poorly defined interface... a better example would have been things like DbCommand
etc, which do this - but that is harder to show in a short example)
class Foo : ICloneable
{
public Foo Clone() { return CloneCore(); }
object ICloneable.Clone() { return CloneCore(); }
protected virtual Foo CloneCore() { ... }
}
class Bar : Foo
{
protected override Foo CloneCore() { ... }
public new Bar Clone() { return (Bar)CloneCore(); }
}
If we had used a public virtual method, we wouldn't be able to override
it and use new
in the base-class, as you aren't allowed to do both:
class A
{
public virtual A SomeMethod() { ... }
}
class B : A
{
public override A SomeMethod() { ... }
//Error 1 Type 'B' already defines a member called 'SomeMethod' with the same parameter types
public new B SomeMethod() { ... }
}
Using the protected virtual approach, any usage:
all use the correct CloneCore()
implementation for the concrete type.