I'm tring to do :
public abstract class Base
{
public abstract Task Execute();
}
public abstract class Concrete<T> : Base where T : class
{
new public abstract Task<T> Execute();
}
But for some reason I am getting the compiler error :
CS0533 'Concrete.Execute()' hides inherited abstract member 'Program.Base.Execute()
I've hidden plenty of members in the past but never met this side case and I'm quite puzzled here. Spent a long time on MSDN and the web but couldn't find anything about this behaviour.
I would really appreciate any insight on the issue.
Here's the fiddle.
The problem is that the base method is abstract. A class inheriting from Concrete<T> would have to override Base.Execute(), but it could not override it, because it is hidden by Derived<T>.Execute(). So, Concrete<T> would be an abstract class that can't possibly have any implementation (at least not in C#), at thus it would be useless. So, the C# compiler does not let you write it.
If Base was an interface, you could work around this by using an explicit interface implementation. But there is nothing like explicit base class implementation, so I don't think there is any way to have this kind of code, at least not without renaming one of the two methods.
From MSDN :
An abstract method declaration introduces a new virtual method but
does not provide an implementation of that method. Instead,
non-abstract derived classes are required to provide their own
implementation by overriding that method
Well, the reason for this error is how abstractions work in C#, abstraction can be inherited, it can be implemented but it cannot be hidden or replaced by another abstraction.
Besides, consider the code :
public abstract class Base
{
public abstract Task Execute();
public abstract Task<int> Execute();
}
This will not compile, because :
Type 'Base' already defines a member called 'Execute' with the same
parameter types
So why should it work when we move the second method to a derived abstract class ?
Related
Just out of curiosity I tried overriding a abstract method in base class, and method the implementation abstract. As below:
public abstract class FirstAbstract
{
public abstract void SomeMethod();
}
public abstract class SecondAbstract : FirstAbstract
{
public abstract override void SomeMethod();
//?? what sense does this make? no implementaion would anyway force the derived classes to implement abstract method?
}
Curious to know why C# compiler allows writing 'abstract override'. Isn't it redundant? Should be a compile time error to do something like this. Does it serve to some use-case?
Thanks for your interest.
There's a useful example for this on Microsoft Docs - basically you can force a derived class to provide a new implementation for a method.
public class D
{
public virtual void DoWork(int i)
{
// Original implementation.
}
}
public abstract class E : D
{
public abstract override void DoWork(int i);
}
public class F : E
{
public override void DoWork(int i)
{
// New implementation.
}
}
If a virtual method is declared abstract, it is still virtual to any
class inheriting from the abstract class. A class inheriting an
abstract method cannot access the original implementation of the
method—in the previous example, DoWork on class F cannot call DoWork
on class D. In this way, an abstract class can force derived classes
to provide new method implementations for virtual methods.
I find it really useful for ensuring proper ToString() implementation in derived classes. Let's say you have abstract base class, and you really want all derived classes to define meanigful ToString() implementation because you are actively using it. You can do it very elegantly with abstract override:
public abstract class Base
{
public abstract override string ToString();
}
It is a clear signal to implementers that ToString() will be used in base class in some way (like writing output to user). Normally, they would not think about defining this override.
Interestingly enough, the Roslyn version of the C# compiler has an abstract override method in it, which I found odd enough to write an article about:
http://ericlippert.com/2011/02/07/strange-but-legal/
Imagine that SecondAbstract is in the middle of a three-class hierarchy, and it wants to implement some abstract methods from its base FirstAbstract while leaving some other method X to be implemented from its child ThirdAbstract.
In this case, SecondAbstract is forced to decorate the method X with abstract since it does not want to provide an implementation; at the same time, it is forced to decorate it with override since it is not defining a new method X, but wants to move the responsibility of implementing X to its child. Hence, abstract override.
In general, the concepts modelled by abstract and override are orthogonal. The first forces derived classes to implement a method, while the second recognizes that a method is the same as specified on a base class and not a new one.
Therefore:
neither keyword: "simple" method
abstract only: derived class must implement
override only: implementation of method defined in base class
abstract override: derived class must implement a method defined in base class
This is done because in child class you can not have abstract method with same name as in base class. override tells compiler that you are overriding the behavior of base class.
Hope this is what you are looking for.
If you did not declare SomeMethod as abstract override in SecondAbstract, the compiler would expect that class to contain an implementation of the method. With abstract override it is clear that the implementation should be in a class derived from SecondAbstract and not in SecondAbstract itself.
Hope this helps...
This design pattern is known as the Template Method pattern.
Wikipedia page on Template Methods
A simple, non-software example: There are a bunch of military units: tanks, jets, soldiers, battleships, etc. They all need to implement some common methods but they will implement them very differently:
Move()
Attack()
Retreat()
Rest()
etc...
I read an article from some site and in that article i read this :
Abstract classes can add more functionality without destroying the child classes that were using the old version. In an interface, creation of additional functions will have an effect on its child classes, due to the necessary implementation of interface methods to classes.
I don't understand what it means. Can anyone explain this more specifically , with a Good Example ?
this is the article which i read Link
Because interfaces only define members that types must implement, adding any new member to an interface will break any class that implements the old version because it inherently doesn't implement the new member. Any time you change the definition of an interface you must change every single class that implements that interface. Adding an abstract member to an abstract class does the same for derived classes but if you add a virtual member to the abstract class then it will have no impact on derived classes. They can be changed to override that member but they don't have to.
What it means is that if you consider a Abstract Class called Phone
and it has 3 virtual functions i.e.
AddPhonePrice , AddAccessoryPrice, AddAuxillaryPrice
and if there are two child classes
1) SamsungPhone 2) Iphone
now SamsungPhone will have implementation for all 3 functions.
while Iphone will have implementation for only AddPhonePrice, since they dont provide anything else with the phone
if we make interface called IMainPhone with
AddPhonePrice , AddAccessoryPrice, AddAuxillaryPrice functions
then both SamsungPhone and Iphone will need to implement all 3 functions
irrespective of whether they need them or not.
This means that you are able to add new members (methods, properties, fields, ...) to abstract classes that do not lead to changes in the derived classes - as long as the members are not abstract this is correct. For instance, consider this example:
internal abstract class MyBaseClass
{
public abstract void DoSomething();
// This method can also be added later without having an effect on the derived classes
public virtual void DoSomethingElse()
{
// Do something else...
}
}
internal class MyDerivedClass : MyBaseClass
{
public override void DoSomething()
{
// Do something...
}
}
In this case, the derived class has to implement the method DoSomething. But you can add non-abstract functions to the abstract base class later on. However, as soon as you add another abstract member to the base class, this also affects all non-abstract derived classes because the must implement the new members.
An interface on the other hand does not define concrete implementations at all but does only contain the abstract signature that all implementors must provide. Therefore, if you add a new member (method, property) to an interface it forces all implementors of the interface to also provide an implementation of the new members.
Interface: When you add a method to the base interface class, then you have to (manually) make sure all of the derived classes implement that method.
Abstract Base: When you add a method to an abstract base class, you aren't required by the compiler to implement that method in the derived classes.
Wait, before you start thinking, I would like to clear that I am NOT going to ask the routine differences between Interface and Abstract.
I had gone through the difference between Abstract and Interface in MSDN.
It is said :
By updating the base class, all inheriting classes are automatically updated with the change.
Interfaces, on the other hand, cannot be changed once created. If a new version of
an interface is required, you must create a whole new interface.
See this : -
Can anyone prove this using following example: -
abstract class WashingMachine
{
abstract public void Wash();
}
class Philips : WashingMachine
{
public Philips() { }
override public void Wash(){//Wash code here....}
}
class Samsung : WashingMachine
{
public Samsung() { }
override public void Wash(){//Wash code here....}
}
class Videocon : WashingMachine
{
public Videocon() { }
override public void Wash(){//Wash code here....}
}
Now, If I added following new abstract method in WashingMachine : -
abstract public void Rinse(int loadSize);
How all inheriting classes (i.e. Philips/Samsung/Videocon) will automatically get updated with the change?
They won't get updated - you still have to manually add an implementation of Rinse to each and every class that inherits from WashingMachine.
What I believe the MSDN says is that if you have a non-abstract method defined in an abstract class and you change that method, all classes that inherit from the abstract class will benefit from the change automatically.
Your concrete derived types all need to provide an implementation of any inherited abstract member...thus your types will still need to provide a Rinse implementation when you modified the base.
http://msdn.microsoft.com/en-us/library/sf985hc5(v=vs.71).aspx
This is a confusion programmers normally get when read difference between interface and abstract class. the line you refer is only true if the change in the abstract class is concrete. what i mean is you added a property or a method with implementation. Or if i am more specific, any change in base abstract class which does not make any concrete class abstract. Such change is possible in abstract classes and there is no way you can add such change in interface.
How all inheriting classes (i.e. Philips/Samsung/Videocon) will automatically get updated with the change?
They will suddenly become non-compileable, isn't that an update?
But I'd like to point out that there's in fact no difference between abstract method in abstract class and method in interface. Main difference lies in the fact that abstract classes can have methods with implementation and interfaces can not.
In fact, I'd say that I don't like MSDN definition and find it confusing and somewhat misleading.
Just out of curiosity I tried overriding a abstract method in base class, and method the implementation abstract. As below:
public abstract class FirstAbstract
{
public abstract void SomeMethod();
}
public abstract class SecondAbstract : FirstAbstract
{
public abstract override void SomeMethod();
//?? what sense does this make? no implementaion would anyway force the derived classes to implement abstract method?
}
Curious to know why C# compiler allows writing 'abstract override'. Isn't it redundant? Should be a compile time error to do something like this. Does it serve to some use-case?
Thanks for your interest.
There's a useful example for this on Microsoft Docs - basically you can force a derived class to provide a new implementation for a method.
public class D
{
public virtual void DoWork(int i)
{
// Original implementation.
}
}
public abstract class E : D
{
public abstract override void DoWork(int i);
}
public class F : E
{
public override void DoWork(int i)
{
// New implementation.
}
}
If a virtual method is declared abstract, it is still virtual to any
class inheriting from the abstract class. A class inheriting an
abstract method cannot access the original implementation of the
method—in the previous example, DoWork on class F cannot call DoWork
on class D. In this way, an abstract class can force derived classes
to provide new method implementations for virtual methods.
I find it really useful for ensuring proper ToString() implementation in derived classes. Let's say you have abstract base class, and you really want all derived classes to define meanigful ToString() implementation because you are actively using it. You can do it very elegantly with abstract override:
public abstract class Base
{
public abstract override string ToString();
}
It is a clear signal to implementers that ToString() will be used in base class in some way (like writing output to user). Normally, they would not think about defining this override.
Interestingly enough, the Roslyn version of the C# compiler has an abstract override method in it, which I found odd enough to write an article about:
http://ericlippert.com/2011/02/07/strange-but-legal/
Imagine that SecondAbstract is in the middle of a three-class hierarchy, and it wants to implement some abstract methods from its base FirstAbstract while leaving some other method X to be implemented from its child ThirdAbstract.
In this case, SecondAbstract is forced to decorate the method X with abstract since it does not want to provide an implementation; at the same time, it is forced to decorate it with override since it is not defining a new method X, but wants to move the responsibility of implementing X to its child. Hence, abstract override.
In general, the concepts modelled by abstract and override are orthogonal. The first forces derived classes to implement a method, while the second recognizes that a method is the same as specified on a base class and not a new one.
Therefore:
neither keyword: "simple" method
abstract only: derived class must implement
override only: implementation of method defined in base class
abstract override: derived class must implement a method defined in base class
This is done because in child class you can not have abstract method with same name as in base class. override tells compiler that you are overriding the behavior of base class.
Hope this is what you are looking for.
If you did not declare SomeMethod as abstract override in SecondAbstract, the compiler would expect that class to contain an implementation of the method. With abstract override it is clear that the implementation should be in a class derived from SecondAbstract and not in SecondAbstract itself.
Hope this helps...
This design pattern is known as the Template Method pattern.
Wikipedia page on Template Methods
A simple, non-software example: There are a bunch of military units: tanks, jets, soldiers, battleships, etc. They all need to implement some common methods but they will implement them very differently:
Move()
Attack()
Retreat()
Rest()
etc...
I've stumbled upon this "feature" of C# - the base class that implements interface methods does not have to derive from it.
Example:
public interface IContract
{
void Func();
}
// Note that Base does **not** derive from IContract
public abstract class Base
{
public void Func()
{
Console.WriteLine("Base.Func");
}
}
// Note that Derived does *not* provide implementation for IContract
public class Derived : Base, IContract
{
}
What happens is that Derived magically picks-up a public method, Base.Func, and decides that it will implement IContract.Func.
What is the reason behind this magic?
IMHO: this "quasi-implementation" feature is very-unintuitive and make code-inspection much harder. What do you think?
The reason is that your comment is simply incorrect:
// Note that Derived does not provide implementation for IContract
Sure it does. Follow the logic through.
Derived is required to provide a public member corresponding to each member of IContract.
All inheritable members of a base class are also members of a derived class; that's the definition of inheritance.
Therefore Derived provides an implementation for IContract; its inherited member is a member that fulfills the requirement
Therefore, no error.
this feature is very-unintuitive and make code-inspection much harder. What do you think?
I think you shouldn't use the feature if you don't like it. If you find it confusing and weird to read code that uses this feature then encourage your coworkers who use this feature to stop doing so.
How is this feature different from any other feature where a method from a base class is used from a derived class? There are a number of different ways in which a method from a base class may be used or mentioned in a derived class -- method calls, overrides, method group conversions, and so on.
Furthermore, this is relatively speaking a simple, straightforward case. If you really want to complain about confusing interface semantics in C#, I'd spend my time complaining about interface reimplementation semantics. That's the one that really seems to bake people's noodles. I always have to look that thing up in the spec to make sure I'm getting the semantics right.
Why do you think that this is strange and unnatural? Every public member of base class is also a public member of derived class. So there is no contradiction here. Anyhow you can implement interface explicitely if you like.