Strange, but legal

Strange, but legal

Rate This
  • Comments 19

"Can a property or method really be marked as both abstract and override?" one of my coworkers just asked me. My initial gut response was "of course not!" but as it turns out, the Roslyn codebase itself has a property getter marked as both abstract and override. (Which is why they were asking in the first place.)

I thought about it a bit more and reconsidered. This pattern is quite rare, but it is perfectly legal and even sensible. The way it came about in our codebase is that we have a large, very complex type hierarchy used to represent many different concepts in the compiler. Let's call it "Thingy":

abstract class Thingy
{
  public virtual string Name { get { return ""; } }
}

There are going to be a lot of subtypes of Thingy, and almost all of them will have an empty string for their name. Or null, or whatever; the point is not what exactly the value is, but rather that there is a sensible default name for almost everything in this enormous type hierarchy.

However, there is another abstract kind of thingy, a FrobThingy, which always has a non-empty name. In order to prevent derived classes of FrobThingy from accidentally using the default implementation from the base class, we said:

abstract class FrobThingy : Thingy
{
  public abstract override string Name { get; }
}

Now if you make a derived class BigFrobThingy, you know that you have to provide an implementation of Name for it because it will not compile if you don't.

  • The other case I have seen this is when you wish to make the subclass author decide if the default implementation is valid for them, but you still wish to provide a default implementation, so you have an abstract method with a body.  When this happens below the “root” you get an “abstract override” method.   (For some reason I saw this a lot in C++ code bases I worked on)

  • @Kyle, @Ian, unlike abstract classes, which can in fact be fully implemented yet marked abstract, you cannot have a body for methods marked abstract. @Kyle, the pattern you might be remembering would be for interface implementation, where methods would be given such bodies automatically by the IDE or, of course, manually by the programmer.

  • "There is no way for Ghostdoc to do it right because what is private for some is public for others."

    Well, one "fix" is to assume XML docs are for public API only. Then Ghostdoc could produce a default doc tailored only to the public members.

    I know I'm not the only one who often doesn't bother to put XML docs on non-public members.

  • I too use this pattern to ensure a meaningful ToString() implementation:

       Public MustOverride Overrides Function ToString() As String

Page 2 of 2 (19 items) 12