What is the proper way to override explicit implementations of an interface in a child class?
public interface ITest
{
string Speak();
}
public class ParentTest : ITest
{
string ITest.Speak()
{
return "Meow";
}
}
public class ChildTest : ParentTest
{
// causes compile time errors
override string ITest.Speak()
{
// Note: I'd also like to be able to call the base implementation
return "Mooo" + base.Speak();
}
}
The above is a best guess for the syntax, but obviously it's wrong. It causes the following compile time errors:
error CS0621:
`ChildTest.ITest.Speak()': virtual or abstract members cannot be
private
error CS0540:
ChildTest.ITest.Speak()': containing type does not implement
interfaceITest'
error CS0106:
The modifier `override' is not valid for this item
I can actually get this to work without using explicit interfaces so it's not actually blocking me but I would really like know, for my own curiosity, what is the correct syntax if wanted to do this with explicit interfaces?
An explicit interface implementation cannot be a virtual member. See section 13.4.1 of the C# language specification (it is outdated but this logic does not appear to have changed in C# 6.0). Specifically:
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.
This means, you will never be able to directly override this member.
What you can do as a workaround is to call another virtual method from your explicit implementation:
class Base : IBla
{
void IBla.DoSomething()
{
this.DoSomethingForIBla();
}
protected virtual void DoSomethingForIBla()
{
...
}
}
class Derived : Base
{
protected override void DoSomethingForIBla()
{
...
}
}
I also had a situation where I thought I wanted to override an explicit interface implementation and call the base class and found this question with its answers saying "can't be done".
The first thing to note is that in order to override the explicit interface implementation WITHOUT calling the base class is fairly simple. The derived class merely needs to implement the interface itself.
public class ChildTest : ParentTest, ITest
{
string ITest.Speak()
{
return "Mooo";
}
// Note: any other interface functions will call ParentTest's implementation
}
However, there is now no "legitimate" way to call ParentTest's implementation of ITest.Speak on an object of type ChildTest, as any attempt to use the interface will result in ChildTest's implementation being called instead.
Thus, it is only the call to the base implementation that causes complication. To satisfy my curiosity, I proved that it CAN be done, but really it shouldn't...
Leaving the base class unchanged, the following does in fact allow the base class to be called using reflection.
public class ChildTest : ParentTest, ITest
{
string ITest.Speak()
{
return "Mooo" + typeof(ParentTest).GetMethod("ITest.Speak", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(this, new object[0]) as string;
}
}
NB if the sample code is enclosed in a namespace, the fully qualified interface name is required. e.g. "MyNamespace.ITest.Speak"
If the function will be called repeatedly and/or for many objects, performance can be improved by caching the method info, and/or creating a delegate for the base call, e.g.:
public class ChildTest : ParentTest, ITest
{
static ChildTest()
{
baseSpeakMethodInfo = typeof(ParentTest).GetMethod("ITest.Speak", BindingFlags.Instance | BindingFlags.NonPublic);
}
static private MethodInfo baseSpeakMethodInfo;
public ChildTest()
{
baseSpeak = baseSpeakMethodInfo.CreateDelegate(typeof(Func<string>), this) as Func<string>;
}
private Func<string> baseSpeak;
string ITest.Speak()
{
return "Mooo" + baseSpeak();
}
}
The only advantage this has over other answers is that it works if you cannot modify the base class. Otherwise, it's a horrible solution, and a mechanism should be created in the base class (as in other answers) to provide the derived class with a legitimate way to call the base implementation.
You can use a protected virtual method, and keep the implementation non-public, so you still have explicit interface implementation which is just a wrapper around the implementation:
public class ParentTest : ITest
{
protected virtual string Speak_Impl()
{
return "Meow";
}
string ITest.Speak()
{
return Speak_Impl();
}
}
public class ChildTest : ParentTest
{
protected override string Speak_Impl()
{
return "Mooo";
}
}
You can't override explicit interface implementations. They cannot be virtual so there's no way to directly override them. You can, however, make them indirectly virtual by having it call a protected virtual member:
public interface ITest
{
string Speak();
}
public class ParentTest : ITest
{
string ITest.Speak()
{
return Speak();
}
protected virtual string Speak()
{
return "Meow";
}
}
public class ChildTest : ParentTest
{
protected override string Speak()
{
return "Mooo";
}
}
public virtual string Speak() in the parent and public override string Speak() in the child should work fine. You cannot use explicit interfaces for this use case. You can work around it by declaring a protected member and calling it in the explicit interface implementations if you need to use them.
Related
I have 1 interface IMetadata which i want to restrict access to only current assembly(class library) and not outside of that and hence I have marked it as internal.
Now I want to inject this interface to my base abstract class and call method of IMetadata on my base class method to perform some logic. Base class will receive versioning from derive class Type1 for instance hence i have marked base abstract class constructor as protected but I am getting below error :
Inconsistent Accessibility : Parameter type IMetadata is less
accessible than BaseType.BaseType(IMetadata)
But this metadata will always going to receive its concrete type from derive class(Type1) hence I want this base class constructor as protected and also I want Metadata to be only available in current assembly and not outside of it.
internal interface IMetadata
{
string CreateMetadata();
}
internal class Metadata : IMetadata
{
public Metadata(string location)
{
this.location = location;
}
public string CreateMetadata()
{
}
}
public interface IBaseType
{
Void Perform();
}
public abstract class BaseType : IBaseType
{
private readonly IMetadata _metadata;
protected BaseType(IMetadata metadata) //error
{
}
}
class Type1 : BaseType
{
public Type1(IMetadata metadata) :
base(metadata)
{
}
}
Can anybody tell me whats the problem and how do I achieve this encapsulation?
The reason the compiler performs these accessibility checks is to try to steer you into the "pit of success". You have "thingy" that you've marked (or allowed to default) as internal. That means it's an implementation detail within your assembly. Nothing outside of your assembly should know or care what this "thingy" is. It certainly won't be able to "say it's name" or create one.
You then write something that is public or protected. These are things which are visible to other assemblies. And then you're saying "in order to use this, you have to supply a thingy". You've leaked an implementation detail and that's why the compiler stops you. You need to look hard at this and either decide that it's not purely an implementation detail (and so make it public) or that you shouldn't be exposing it outside of your assembly.
Ideally you mark this constructor as private protected which carries the correct semantics - only the intersection of {classes inheriting from this class} and {classes within this assembly} can call it. Only other members of your assembly can get hold of the required instance anyway.
However, if you're not yet on C#7.2, you have to make a choice. I'd go with internal. It's an abstract class anyway, nobody can directly construct it even with a constructor that notionally isn't related to the inheritance hierarchy.
This compiles just fine and shows both approaches:
internal interface IMetadata
{
string CreateMetadata();
}
internal class Metadata : IMetadata
{
private readonly string location;
public Metadata(string location)
{
this.location = location;
}
public string CreateMetadata()
{
return string.Empty;
}
}
public interface IBaseType
{
void Perform();
}
public abstract class BaseType : IBaseType
{
private readonly IMetadata _metadata;
private protected BaseType(IMetadata metadata) //No error
{
}
internal BaseType(IMetadata metadata, int thing) //No error
{
}
public abstract void Perform();
}
class Type1 : BaseType
{
public Type1(IMetadata metadata) :
base(metadata)
{
}
public Type1(IMetadata metadata, int thing) : base(metadata, thing)
{
}
public override void Perform()
{
throw new NotImplementedException();
}
}
My abstract class has a method that is abstract like this:
public abstract void Run(BaseType baseType);
And now in my derived class which has to implement this function, i want it to only accept a specific derived type from BaseType
So it would have:
public override void Run(DerivedType derivedType){}
Is there any way to enforce this at all ?
Currently i have to do:
public override void Run(BaseType baseType) {
if(!(baseType is DerivedType)) {
// throw exception
}
}
It's not very strict with enforcing the type - i was wondering if there is a way to do so without the need to constantly add a type check ?
I've sometimes used this pattern:
public interface IHandler
{
void Run();
}
public abstract class BaseHandler<TObj> : IHandler
where TObj: BaseType
{
protected readonly TObj _obj {get;set;}
public BaseHandler(TObj obj)
{
this._obj = obj;
}
public abstract void Run();
}
public class DerivedHandler : BaseHandler<DerivedType>
{
public DerivedHandler(DerivedType obj) : base(obj)
{
}
public override void Run()
{
// do stuff with base._obj
}
}
public class HandlerService
{
public IHandler CreateHandler<TObj>(TObj obj)
{
// Depending on your DI container, you could resolve this automatically from the container
if (typeof(TObj) == typeof(DerivedType))
{
return new DerivedHandler(obj);
}
throw new NotImplementedException();
}
}
This allows you to define a specific "handler" for each derived type, and then access it through a common interface.
The idea is that you instantiate a specific handler for the object, and then methods like Run() operate on that object. You can then resolve a handler through the service.
I'll fill in some more info later when I have time.
You want the language to do something that it really shouldn't. You want a covariant argument, which violates the Liskov Substitution Principle: It makes the implementation of the abstract class not usable in every situation where the abstract base class is usable. This is the whole point of abstract base classes to begin with.
Although it could make sense to have a covariant return type (returning a more derived type then the abstract methods specifies) the language also prevents you to do that.
Let's say I have an interface as follows.
interface CardHolder : IEnumerable<Card>
{
/// <summary> ...
void PutCard(Card card);
/// <summary> ...
void PutCards(Card[] card);
/// Some more methods...
}
I implement it as follows.
public class ArrayCardHolder : CardHolder
{
private Card[] _cards;
private int _size = 0;
public ArrayCardHolder(int capacity)
{
_cards = new Card[capacity];
}
public void PutCard(Card card)
{
if (IsFull())
throw new Exception("This CardHolder is full. Capacity: " + Capacity());
_cards[_size++] = card;
}
public void PutCards(Card[] cards)
{
if (_size + cards.Length > _cards.Length)
throw new Exception("Adding the Cards would exceed this CardHolder its capacity. Capacity: " + Capacity());
for (int index = 0; index < cards.Length; index++)
_cards[_size++] = cards[index];
}
public IEnumerator<Card> GetEnumerator()
{
for (int index = 0; index < _size; index++)
yield return _cards[index];
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
///More methods.
}
Why can I not use the override keyword in my ArrayCardHolder
(e.g. public void override PutCard(Card card) { ///implementation } to indicate that the method implements (i.e. overrides) the interface? In that case, the project will refuse to build.
Why does it work however when overriding ToString()? And why doesn't it work when implementing CompareTo(T t) from IComparable<T>?
What should I use instead? I'm worried that the documentation from the interface will not apply to my implementing methods. Such is the case in Java when the #Override annotation is used.
Interface's methods are not overriden, they are implemented. You are confused with abstract/virtual methods which can be overriden.
Example:
public interface IFoo
{
void DoA();
}
public abstract class BaseFoo : IFoo
{
public void DoA() { } // *this HAS to be implemented*
public virtual void DoB() { }
}
public abstract class MyFoo : BaseFoo
{
// *this CAN be implemented, which would override the default implementation*
public override void DoB() { }
}
As others metioned, ToString is a virtual method of the base class object, that is why you can override it.
You can override any method of base type if it is marked as virtual. For example you can override ToString() method as it is marked virtual in object class. And object is the base type in .Net.
public override string ToString()
{
return base.ToString();
}
Interfaces are implemented because they done have any implementation, hence there is nothing to override. For Example IComparable is an interface with CompateTo() method, It has no implementation, Hence you implement it in the class inheriting this interface.
public int CompareTo(object obj)
{
throw new NotImplementedException();
}
I hope I made it clear.
As mentioned abundantly, override applies to virtual and abstract method implementations, not interface method implementations.
The annoying thing about all of this is that there is no way to generate warnings when a method that used to implement an interface method becomes orphaned.
Interestingly, java tooling has an option to allow #override on interface methods, so that errors/warnings will be generated when an interface method becomes orphaned.
The question, from a language implementation point of view would be whether an override of a interfacement method would be virtual or not. I suppose "override virtual" would be an option. Or "override abstract".
https://github.com/dotnet/csharplang/issues/3510
So technically, the answer to WHY is not "because you can't", but something deeper and more sinister; namely: because the C# language spec is wrong. Just saying. :-P
An "interface" is a description of "what the public-facing face of some particular programming-thing must look like."
Any "concrete implementation" of that interface must do (at least) everything that the interface called for. (How it "gets 'er done" is entirely up to the implementor.)
So now, let's say that you've got two classes, Dad and Teenager, both of whom implement the same interface. But Teenager (although obviously a descendent of Dad) wants to do one of those things ... say, play_music ... a little bit differently. Teenager can override Dad's method.
So long as Teenager's implementation continues to conform to the strictures of the interface, our teen can play his music just as loudly as he likes.
You are not overriding methods, you are implementing members of an interface.
In C#, override is only used when you are overriding an existing implementation. A case of this is ToString(). The method you are overriding must be marked virtual on the base class.
.ToString is a virtual method in a base class Object . That's why you can override it. But you don't override an interface method, you implement it.
If you want to provide a default implementation and maybe override it in a class, then you need to use a base class with a virtual method. So :
Interface method: You must provide implementation in the class.
Abstract method: You must provide implementation in the derived class.
virtual method: you may provide implementation in the derived class or keep the default implementation. (or mix both by calling base.MethodName(); then providing additional code)
Example:
public interface IContract
{
// It is a must to implement this method in classes
void MustImplement();
}
public abstract class BaseClass
{
// Just signature, No implementation. It is a must to implement.
public abstract void IAmAbstract();
public virtual void IAmVirtual()
{
Console.WriteLine("I provide default implementation");
}
}
public class DerivedClass : BaseClass, IContract
{
public override void IAmAbstract()
{
Console.WriteLine("provides Abstract Method implementation In Derived Class");
}
// It is optional to override this method
public override void IAmVirtual()
{
// class default implementation
base.IAmVirtual();
Console.WriteLine("provides Additional virtual Method implementation In Derived Class");
}
public void MustImplement()
{
Console.WriteLine("provides Interface Method implementation In Derived Class");
}
}
If I have two classes that both implement an interface, but also inherit, do I need to make the function virtual? eg given:
interface IDoSomething
{
void DoSomething();
}
class A : IDoSomething
{
public void DoSomething()
{
//do A
}
}
class B : A
{
public new void DoSomething()
{
//do B
}
}
Would the following code do A or B?
IDoSomething doer = new B();
doer.DoSomething(); //do A or do B?
I'm getting confused because I'm under the impression that all inteface calls are effectively virtual, but obviously I am using the new operator to hide the base definition.
Here is the explanation. Already available at stackoverflow forums.
Quoting Jeffrey Ritcher from CLR via CSharp 3rd Edition here
The CLR requires that interface methods be marked as virtual. If you
do not explicitly mark the method as virtual in your source code, the
compiler marks the method as virtual and sealed; this prevents a
derived class from overriding the interface method. If you explicitly
mark the method as virtual, the compiler marks the method as virtual
(and leaves it unsealed); this allows a derived class to override the
interface method. If an interface method is sealed, a derived class
cannot override the method. However, a derived class can re-inherit
the same interface and can provide its own implementation for the
interface’s methods.
class A : IDoSomething
{
public virtual void DoSomething()
{
//do A
}
}
class B : A
{
public override void DoSomething()
{
//do B
}
}
I prefer leppie's solution. If that's not an option:
class A : IDoSomething
{
void IDoSomething.DoSomething()
{
//do A
}
}
class B : A
{
void IDoSomething.DoSomething()
{
//do B
}
}
But note that this will hide the implementation, so you can't do ((A)doer).DoSomething().
If you can't change class A to either of these solutions, I don't think there's a sure way to override it in all cases. You could both explicitly implement the interface and make a public new method on B. That way if it's statically known as an IDoSomething or as a B it will use B's implementation, but if it's known as an A it will still use A's implementation.
Although C# and .net allow derived classes to re-implement interface methods, it is often better to have the base class use a virtual method to implement the interface, and have the derived class override that method, in any situation where a derived class might wish to augment, rather than entirely replace, the base-class implementation. In some languages like vb.net, this can be done directly regardless of whether a class exposes a public member with the same name and signature as the interface member being implemented. In other languages like C#, a public method which implements an interface can be marked unsealed and virtual (allowing a derived class to override it and have that override call base.Member(params) but an explicit interface implementation cannot. In such languages, the best one can do is something like:
class MyClass : MyInterface
{
void MyInterface.DoSomething(int param)
{
doSomething(param);
}
protected virtual void doSomething(int param)
{
...
}
}
class MyClass2 : MyClass
{
protected override void doSomething(int param)
{
...
base.doSomething(param);
...
}
}
In some cases, having the interface implementation wrap a virtual call can be advantageous, since it allows the base class to ensure that certain things happen before or after the overridden function. For example, a non-virtual interface implementation of Dispose could wrap a virtual Dispose method:
int DisposingFlag; // System.Boolean doesn't work with Interlocked.Exchange
void IDisposable.Dispose()
{
if (Threading.Interlocked.CompareExchange(DisposingFlag, 1, 0) == 0)
{
Dispose(true);
DisposingFlag = 2;
Threading.Thread.MemoryBarrier();
GC.SuppressFinalize(this);
}
}
public bool Disposed { get {return (DisposingFlag != 0);} }
public bool FullyDisposed { get {return (DisposingFlag > 1);} }
This will (unlike Microsoft's default wrapper) ensure that Dispose only gets called once, even if multiple threads try to call it simultaneously. Further, it makes a Disposed property available. Using Microsoft's wrapper, every derived class that wants a Disposed flag would have to define its own; even if the base-class Disposed flag were protected or public, it wouldn't be safe to use because it wouldn't get set until after derived classes had already begun cleanup. Setting DisposingFlag within the wrapper avoids that problem.
Interface methods in C# can be implemented explicitly, so that their implementation is invoked when an instance is explicitly cast to the interface type. Why is this not also supported on virtual methods of classes?
Although working around the 'multiple inheritance' issue is unique to interfaces, it seems that for every other reason that explicitly implemented members would be useful for interfaces, they would also be useful for virtual methods. A cleaner return-type covariance model springs to mind.
Edit: By request, an example:
public class Foo {
...
}
public class Bar : Foo {
...
}
class Base {
abstract Foo A ();
}
class Dervied {
private Bar _b;
Bar A () {
return _b;
}
Foo Base.A () {
return _b;
}
}
I am aware of using helper methods to simulate this, but the net effect seems to have any of the bad characteristics that explicit implementation would have, but with a dirtier API. The crux of my question is not how to do return type covariance, but why a similar mechanism for interfaces is not supported for virtual methods.
Some people recommend not having public virtual methods in the first place. But instead create one public non virtual method representing the consumer interface, and one protected virtual method representing the implementer interface.
I would not call separating the contracts for caller and implementer "muddying the design". In many cases it's cleaner IMO, but I'm usually too lazy to actually do it that way.
This design works much better with return type covariance and method hiding.
An additional benefit of this is that the public wrapper can add additional checking code and supports different contracts for the caller and implementer.
An example of how I'd emulate return type covariance:
public class Base
{
protected virtual Base FooOverride(int i){return new Base();};//FooOverride does not need to duplicate the argument checking
public Base Foo(int i)
{
if(i<0)
throw new ArgumentException("i<0");
return FooOverride(i);
}
}
public class Derived:Base
{
protected override Base FooOverride(int i){return new Derived();};
public new Derived Foo(int i)
{
return (Derived)base.Foo();
}
}
What benefit would that have, besides from allowing something like this?
class Base
{
virtual void M() { }
}
class Derived : Base
{
override void M() { }
override void Base.M() { }
}
This effectively bakes a violation of the Liskov Substitution Principle into the C# language - if I have a variable of type Base, calling M() on it can do entirely different things depending on whether the run-time type is Base or Derived.
Explicit interface implementation is different. Say you have this:
interface IFoo
{
void DoStuff();
}
interface IBar
{
void DoStuff();
}
class C : IFoo, IBar
{
void IFoo.DoStuff() { }
void IBar.DoStuff() { }
}
This preserves the LSP - if I have an IFoo variable that happens to be of run-time type C, calling DoStuff() on it will get the IFoo implementation of it. Likewise with IBar.