tobiak777
tobiak777

Reputation: 3365

Cannot hide inherited member compiler error

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.

Upvotes: 3

Views: 1480

Answers (3)

Mike Nakis
Mike Nakis

Reputation: 62045

Other answers have already explained why this error is given.

Here is how to avoid receiving the error:

public abstract class RawAbstract
{
    public Task Execute() => RawExecute(); 
    protected abstract Task RawExecute();
}

public abstract class GenericAbstract<T> : RawAbstract where T : class 
{
    protected override Task RawExecute() => Execute();
    new public abstract Task<T> Execute();
}

public abstract class GenericConcrete<T> : GenericAbstract<T> where T : class 
{
    public override Task<T> Execute() { ... }
}

Upvotes: 0

svick
svick

Reputation: 244918

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.

Upvotes: 4

Fabjan
Fabjan

Reputation: 13676

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 ?

Upvotes: 1

Related Questions