Whilst browsing through some legacy code, I was surprised to encounter an abstract override of a member that was abstract by itself. Basically, something like this:
public abstract class A
{
public abstract void DoStuff();
}
public abstract class B : A
{
public override abstract void DoStuff(); // <--- Why is this supported?
}
public abstract class C : B
{
public override void DoStuff() => Console.WriteLine("!");
}
Isn't the distinction between a virtual or abstract member always available to the compiler? Why does C# support this?
(This question is not a duplicate of What is the use of 'abstract override' in C#? because the DoStuff
-method in class A
is not virtual but abstract as well.)
The most common use of symbols by programmers is for performing language reflection (particularly for callbacks), and most common indirectly is their use to create object linkages. In the most trivial implementation, they are essentially named integers (e.g. the enumerated type in C).
Arrow operator to access the data member of a C Structure We have accessed the values of the data members using arrow operator(->).
C# is a modern object-oriented programming language developed in 2000 by Anders Hejlsberg at Microsoft as a rival to Java (which it is quite similar to). It was created because Sun, (later bought by Oracle) did not want Microsoft to make changes to Java, so Microsoft chose to create their own language instead.
C is one of the earliest and most widely used programming languages. C is the fourth most popular programming language in the world as of January 2022. Modern languages such as Go, Swift, Scala, and Python are not as popular as C. Where is C used today?
To clarify the question: the question is not "why is an abstract override legal?" An existing question handles that. (See also my blog post on the subject.)
Rather, the question is "why is an abstract override legal when the overridden method is also abstract?"
There are several arguments in favour of not giving an error here.
It's harmless.
To give an error, someone on the compiler team must have thought of this scenario and considered it to be worth the time to design the feature, verify that it doesn't cause any bad interactions with other features, write a detailed specification, implement it, test it, write the documentation, translate the error message into two dozen languages, translate the documentation, and maintain the feature forever. What's the compelling benefit that justifies those costs? I see none.
Whenever something looks weird in C# ask yourself what if the base class was owned by someone not on my team and they like to edit it?
Consider for example a variation on your scenario:
public abstract class Z
{
public abstract void DoStuff();
}
public class A : Z
{
public override void DoStuff()
{
throw new NotImplementedException();
}
}
public abstract class B : A
{
public override abstract void DoStuff();
}
The authors of class A realize that they have made a mistake and A and DoStuff should be abstract. Making a class abstract is a breaking change because anyone who says "new A()" is now wrong, but they verify that none of their client teams in their org have created a new A. Similarly, calling base.DoStuff
is now wrong. But again, there are none.
So they change their code to your version of class A. Should class B now have a compile time error? Why? There's nothing wrong with B.
Many features of C# that seem odd are there because the designers consider the brittle base class to be an important scenario.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With