More on virtual by default

Gary and James took issue with my position, so I'd like to expand a bit on what I said.

Gary wrote:

Eric suggests that final should be used in most cases with virtual reserved for the special occasions. I totally disagree, you can't lay down the law as to how another developer is going to extend your class, (other than in the special circumstances I mention here). If the choice is being flexible versus being static, then in the interests of good software engineering you *must* go with the flexible option. Or is that just the Smalltalk programmer in me coming out 🙂

My answer to that question would be “yes”. I'm not being flippant on that, and I'm about as far from being a Smalltalk programmer as you can be, but I think it comes down to the tradeoff between robustness and flexibility. If you allow more extensibility, you are being more flexible, and also being less robust (or, to be precise, being potentially less robust), especially if you aren't testing the extensibility.

James wrote:

The long and short of it - Eric thinks that library designers know everything and that one of the primary jobs is to protect those dumb application developers. There's just no telling what they might do if we let them.

James has it backwards. I don't think that library designers know everything. I think that they know very little about how users might use their classes, and therefore shouldn't be making promises their code can't keep. If they want to support extensibility, then that should be something they design well and test for. If they aren't going to go to that effort, than I don't think providing extensibility that will “probably work” is doing their users a service, and it may be actively doing them a disservice. Not only will such code be more likely to fail, but the constraint of such virtuals limits how the class can evolve in the future. It's bad when you'd like to make a small change that would help 99.9% of your users, but you can't because somebody might have existing code that depends on your behavior. But maybe that's just the compiler guy in me...

I do think that this depends on the kind of library you're building. In general, the more closely coupled the api writer and user ae, theless of an issue this is.

Comments (37)

  1. Eric Wilson says:

    It also matters if the source code for the library is available. For libraries like the .NET framework, being completly virtual does not make a whole lot of sense to me at least, simply because it is difficult to understand all the conditions that a given function may be called under (or even the precise semantics that a given function is required to implement).

  2. Darren Oakey says:

    virtual by default is absurd – it’s just a game of russian roulette! It’s like said above, it’s not a question of knowing what people are going to do with your class – it’s more the fact that BECAUSE YOU DON’T KNOW WHAT THEY ARE GOING TO DO – YOU HAVE TO BE CAREFUL.

    easy example –

    public void Open {_open=true;_pointer = OpenTheFile();}

    public void Close {if (_open) CloseFile(m_pointer);}

    If some idiot starts overriding open, and doesn’t properly set m_open or something, then

    the close will fail badly. Because there is no way of _guaranteeing_ that anyone who override calls the base class, the ONLY safe way of doing the above class is by making them final… and if you do want them sort of overridable, then you make them protected final functions, and make virtual stub functions that call them..

    Especially if you don’t give out your source, I put it to you that the % of functions that it would be REALLY REALLY BAD if someone overrode them and didn’t properly do what those functions did is much much higher than the % of functions that you can safely override!

    (Quite apart from the fact that you want proper encapsulation – I NEVER let any of my coders create a protected class variable – you can make a protected property accessor, but ALL member variables are always private – so it would be impossible to successfully duplicate the functionality of the base class in a child class, without just calling base->function)

  3. Stu Smith says:

    I think the "extensibility makes for less robustness" is a bit of a red-herring to be honest… I’ll start with a couple of examples of problems I’ve had to solve in actual production code:

    1) A Label which truncates the string with ellipses instead of wrapping.

    S.W.F.Label has a member CreateStringFormat() which would have solved the problem. Overriding this to include the appropriate StringTrimming flag would have solved the problem very easily; unfortunately the method is private. The solution I used was to override OnPaint and draw the text myself. However, unless I’m very careful with my implementation, I’m going to lose or break RTL, image animations, color matching, etc.

    2) A TreeView with custom icons.

    I need to draw the icons in the treeview according to some state, and compositing, adding and tracking custom icons in an ImageList would require a lot of work. I can provide custom drawing by responding to TVCUSTOMDRAW messages, but I need to map the handle in the message to the .NET TreeNode (to look up the state). Again there’s a function, this time it’s internal.

    Given that these were requirements (ie I can’t respond with "EricG tells me it would make SWF less robust so you can’t have that feature"), I have the following alternatives:

    a) Roll my own, either partial or complete — less robust

    b) Put in some kluge (eg using reflection to access that method) — less robust

    c) Buy in a third party ccomponent

    So yes, avoiding virtual makes your code more robust, but only by either transferring the flakiness to my code, or by forcing me to not actually use your code at all.

    On a related note, I’d like to propose "Internal considered harmful" (or at least bad form). I tend to find that code with a high ratio of internal to public/private is usually hard to get along with. Unfortunately SWF falls into this category. In example (2), my question is: if this function is useful to other classes in SWF (and it is internal and not private), then why can’t I access it’s usefulness?

    (And incidentally, if anyone has a better solution to either of these sticking points, I’d be most interested, so I can remove my less-robust code).

  4. Richard Curzon says:

    Mom said "don’t run with scissors". Some people by nature, they just seem to NEED to run with scissors. It’s not that they don’t cut themselves… they’re proud of the scars!

    We’ve learned rules about running with scissors in software.

    The original Design Patterns book cautioning to prefer delegation over inheritance, if we want to keep maintenance effort predictable and minimal. In cases where we want to use inheritance, understand the ways the design becomes fragile. How to carefully design for safe extensibility.

    Booch cautioning that encapsulation is a fundamental principle of good software design, but that there is a "tension" between inheritance and encapsulation. Again, how to carefully design for extensibility to avoid the famous "fragility" of inheritance.

    Eric’s comments are completely in line with the Moms Rules of software.

    Still, there will still be lots of people looking for more ways to make bigger and brighter colored scars.

    Thump thump thump, oops, OUCH! Thump thump thump, oops, OUCH! Thump thump thump, oops, OUCH! <big grin>

  5. Now that you mention it, I agree with robustness over flexibility because flexibility is often a mirage.

    Take the HttpWebRequest class for instance. I wanted to override a method that is virtual, but looking at the underlying code of the method, it calls upon methods and objects that are declared private and need to be manipulated. Since I wouldn’t have access to these classes, It’s darn near impossible for me to completely override this method. This is a case where the method perhaps would be better off final, or at least with documentation describing guidelines for overriding it.

  6. GoVirtual says:

    Why oh why does MSFT want to dumb everything down? I don’t need my government running around my house child-proofing everything, and I don’t need MSFT running around the code libraries locking everything down "for my benefit."

    Stu Smith’s comments are dead-on. Read them again if you must. I have been a long-suffering developer who curses monthly at MSFT classes which are so locked down that I cannot extend them even a little bit, and I’m forced to write my own entire version.

    The examples given against going virtual are pretty lame. Take the Open() example. If I override Open() and don’t bother to call base.Open(), I’ll likely eventually get fired. Let the free market do it’s job — bad programmers should be cast aside or set to less challegning tasks.

    Or, why not come up with some attributes that control this behavior?


    virtual void Open() { m_open = true; }

    I’m thinking off the top of my head, so don’t shoot me, but the idea is that if base.Open() is not called by the overriden method, force it to be called anyway. Or at least gen a compiler warning/error if it is not called. Something along those lines. (You may even want to control if it’s auto called at the start of the overriden method, or at the end.) Look, I know that there’s a lot of missing details here, but the fact of the matter is, making the function sealed/final/whatever is really not the solution to the problem.

    It seems that MSFT wants to protect bad programmers from themselves. I’d like to ‘extend that’ (pun intended) and suggest that the real goal should be to protect bad programmers from themselves without constraining good programmers.

    Personally, I resent the fact that MSFT seems to think they have the only good developers, when time-and-time again the holes found in Windows, the bugs in apps, the silly modal error dialogs which prohibit fixing the problem, etc. etc. etc. suggest just the opposite. MSDN Mag is loaded with 3rd party controls which do the exact same as .NET controls, but are more programmer friendly. Why? Because MSFT doesn’t always get it right…shocking, I know.

  7. AndrewSeven says:

    I’ve done my fair share of cursing about sealed classes and final methods, but it is mostly about the specific decisions made to seal/finalize those things.

    I like "Mom’s Rules", I just don’t think that the asp:listitem is sharp and pointy.

  8. Jerry Pisk says:

    I’m sick of Microsoft treating everybody like an idiot. If you don’t know how to code then you shouldn’t be coding. Apparently Microsoft doesn’t want knowledgable people to use their products, because they’re doing everything they can to discourage them while making their products so an idiot (and only an idiot) can use them.

  9. Gary Short says:

    Hey my original post wasn’t designed to be Microsoft bashing, in fact I think that – in general – the .Net framework and VS.Net is one of the best things they’ve done. I don’t think the idea of sealed classes and final is a Microsoft thing either per se.

    All I’m saying is that I feel that a design that seeks to constrain users, simply because a minority of them may get in trouble through their own bad practices, is not a good one.

    If I create a class I can’t possibly imagine all the creative uses that the user community will put it to by extending it, therefore I should only prevent them from doing stuff I *know* will be dangerous and not prevent them from doing things that *might* be dangerous if they get it wrong. I mean, it’s dangerous to drive and blog at the same time, but my laptop still boots up when I’m in the car – it’s down to me to do the sensible thing 🙂

  10. Eric Gunnerson says:


    I’m sorry if people got that impression – I explicitly included the link that you talked about because I thought it made it more clear what your position was.


  11. Kevin Daly says:

    I think the best thing I’ve seen on this issue is "Versioning, Virtual, and Override

    A Conversation with Anders Hejlsberg, Part IV

    " (

    I read that and thought "Ahhhhhhhhhhhh, *that’s* why they do it."

    This is easily one of the more profound differences between C# and Java.

    I was particularly struck by the point about how if everything is virtual by default, then adding a method to the base class breaks any derived class that has a method of the same name and return type. Where’s flexibility then?

  12. damien morton says:

    I think someone proposed a rule something like this:

    "you may not use sealed classes as paramaters or return values in public methods"

    Instead have the sealed class implement an interface and declare interfaces as the paramaters and/or return values.

  13. Thomas Eyde says:

    Some programmers did the most amazing things with the Commodore 64, things which the designers thought where impossible. If they defined what they didn’t know as impossible or not needed and sealed down the whole cbm64, how fun or useful would that have been?

    The Open/Close example given is an excelent example of poor design. It is obvious that these methods are not suitable for overriding, hence they should be sealed. A good designer would have introduced templated method or event.

    I guess we are both right and wrong. Can’t we meet on middle ground and remove the virtual keyword? An ‘override’ should be enought, a missing ‘override’ should mean ‘new’. Having to declare both virtual and override is meaningless.

    You can’t override something which doesn’t exist and a missing override will not, so introducing a new base method with the same name as a derived class method should not break anything. It would keep todays functionallity with simpler syntax.

  14. Richard Curzon says:

    There are still Inheritance 101 classes out there that give everyone the religion…

    Every noob leaves convinced there are no complexities or complications to inheritance. It’s the complete, painless, allpurpose answer for adaptable software, period.

    It’s just not true. It gets complex and error prone (exponentially?) with # of levels and # of methods… just as soon as you get beyond the demo and into real world complexity.

    Unfortunately, you can understand how to dig the hole real fast. But it takes months to grok the real issues. Most of these OO instructors will never know… how could they?

    I meet people who have the 100% virtual faith. But when we talk more than 5 minutes, I get a strong impression they just don’t know what they need to know.

    They have no clue why the GOF book said this, or why Booch said that other thingy. Mostly, they don’t know who those guys are anyway and they don’t care much.

    IMO the answer to a question like "Do they think we are all idiots, when they don’t make everything virtual"… answers itself very nicely <big grin>.

  15. Nicholas Allen says:

    Kevin Daly- that’s actually a good piece for why features like override are nice but most of the discussion on virtual vs. non-virtual is off-track

    > Where’s flexibility then?

    In the derived class. The base class never has flexibility in this case because adding new methods is an incompatible change. Even adding new non-virtual methods can break clients (the problem derives from accessibility during method resolution not inheritance).

  16. John says:

    > If the choice is being flexible versus being static, then in the interests of good software engineering you *must* go with the flexible option <

    No way. Good software engineering is about well considered restriction.

    The old mantra "does one thing well". Flexibility is generally a bad idea.

    If an API can’t be extended the way you want, it’s because either the API sucks, or you’re using the wrong API. It is not because the API isn’t ‘flexible’ enough, it’s just the the API can’t do what you want (and often this may be because what you want to do is a bad idea).


  17. here’s what someone said about this today – he’s a developer using C#, being "protected" by this sort of thinking:

    "Where it could have easily been solved had I been able to extend a StreamReader and access some of the internals, it would have made my life easier. ReadLine returns a line which ends with n, or r, or rn. I needed to change it so it only returned a line that ended with rn. Sure, ReadLine is virtual, but i their infinite wisdom, the library developers decided I would never need to do what I was attempting, and made all the fields private, so it basically left me with only one option, and that was to re-implement the entire class in my own assembly. Damn PITA it was."

    This idea that library designers don’t want to leave things open in order to "protect" developers from limitations is silly. Developers end up doing scads of extra – useless – work as a result of such "help". Nothing forces developers to subclass from you – if you don’t think it’s wise, document that. But tying their hands leads to tons of extra work for no good reason. This is the kind of "help" that drives people nuts

  18. Nicholas Allen says:

    An interesting observation is that a lot of people are arguing virtual by default or non-virtual by default but Eric is the only person I’ve seen in either thread say that the intended user matters when making that decision.

  19. The mistake is in thinking – as the library designer – that you have any idea whatsoever who the "intended user" is. You don’t.

  20. AndrewSeven says:


    One knows exactly who the intended user is, it is someone who uses it in the way it was intended to be used.

    The problem is that one does not often know who the actual user is.

  21. Thomas Eyde says:

    If I declare a base method to be virtual, will it still be safe down the inheritance chain? The arguments for not having virtual as default should apply here as well. You are changing the behaviour of a method when you override it, so the author of the overrided class has no longer control. The original intent may be gone and the virtual is no longer safe.

    So the safer thing to do would be to demand the virtual modifier again if further overriding is wanted. We would then have code like:

    public virtual override void Something()

    If you think this is stupid, why do you think no virtual by default is not?

  22. My take at

    I should point out that the URL might give the wrong impression – my stance is pretty much "pro choice", to use a Roryism.

  23. Mike Dimmick says:

    Now factor in change in the library over time. If a method that wasn’t explicitly intended to be overridden _is_ overridden (i.e. default virtual, and a user decides to override it), and the implementation of the base method is changed in some way, again expecting that it hasn’t been overridden, derived classes could be broken by this change.

    Strongly-named assemblies/side-by-side can help, but if a publisher policy is used to push a different version of the assembly, what then? You have to use <bindingRedirect>s to keep using the old version which worked.

    It’s a lot easier to change a method from final to virtual than the other way around. The first is an almost invisible change; the second is potentially a breaking change.

    On the whole it’s safer only to make the methods you actually want to be extensibility points virtual.

  24. Thomas Eyde says:

    "On the whole it’s safer only to make the methods you actually want to be extensibility points virtual."

    The problem is that the methods I want to make virtual, or think I want to, are not the same ones as you want. There lies the problem.

    I am not a phsycic, I can’t predict the future. Hence virtual by default is better.

    The problem is not the method being virtual, but if someone has overridden it. No potential harm is done if the method is not overridden. You can’t override by default, but have to use the override modifyer. Isn’t that enough?

    It is also very possible to change a virtual method in a breaking way.

  25. Darren Oakey says:

    I still can’t believe this discussion is happening! Especially in this world where we’re all starting to "see the light", and go down TDD routes, this is just one big leap into the dark ages!

    At the moment, without virtual functions, you can make reasonably robust code by knowing about the PreConditions and the PostConditions.

    Ie – suppose we have a function


    It has a post condition "printer is connected". Therefore, any function inside the class can happily assume that post condition – and you can write a piece of code you are absolutely sure will never break…

    HOWEVER – once you make a function virtual, you suddenly LOSE COMPLETELY any understanding of the post condition of the function. ie – you can’t assume ANYTHING about the state of the object or the system after calling that function…

    So – either you end up with a pile of s*** that falls over ever few seconds, or you end up with having to check and verify each and every nuance of state every time you do anything – for instance


    if (WeAreConnectedToPrinter)…

    oops – that won’t work – someone could have overridden the WeAreConnectedToPrinter… ummm …. what do we do? ahhh.. let’s just catch any exception that occurs, and assume it’s all working the way we want?

    is this the sort of thinking you guys are doing? I can’t think of any other way of writing the class – except the much horribly worse "let’s just hope like hell that the user (who is probably not a great coder anyway, if they are jumping to inheritance instead of delegation, who hasn’t seen the code, who has no possible way of knowing completely what this method does) – lets just hope that they don’t make a mistake!

    As well as coding in all the normal languages – I’ve programmed for many many years in both assembler and forth… yet I think I can be more productive in VB or Perl – why? It is the limitations, the boundaries of a language which actually give it power. The fact that you know you don’t have to put worry about disposing this, the garbage collector will do it. The fact that you don’t have to hand calculate the jump table, the compiler will do it – the fact that you don’t have to check the overflow flag every time you do an add – the standard libraries do it..

    I don’t think people realise that productivity and flexibility are OPPOSING FORCES. You get one, you sacrifice the other. ALWAYS.

  26. Thomas Eyde says:

    I am rolling on the floor laughing. It’s funny to see TDD as an argument against virtual by default. Because of TDD you *can* have virtual by default and still be safe. With TDD you can remove all safety nets and still be safe. That said, I still don’t believe sealed/final by default is a safety net. Not with TDD.

  27. Mike Dimmick says:

    I don’t think we should throw away all our other ideas because of TDD. I think we should use as many inspection tools examining the code as we can manage, in a practical sense (there’s no point running e.g. PREfix before check-in, otherwise you’d only manage maybe one check-in a day). The compiler and language are one of those tools. I don’t feel safe in a dynamic-type language.

    TDD can also only work if it can inspect the whole environment – where all code is being tested. In a situation where libraries of components are licensed to and from third-parties, you can still only test for your expected usage patterns. Do TDD people also write unit tests for every component they license from another vendor/part of the platform?

  28. Jerry Pisk says:

    Darren – so what? If somebody decides to break code then let them do it. It is their choice. If you can’t override functions and do it safely then just don’t do it but don’t force your opinions about what should be allowed or not on the rest of us.

  29. damien morton says:

    I can think of reasons why a developer might not want to release code that can be easily extended – i.e. not wanting users to become reliant on features or behaviors that might change under them in a later release.

    I also tend to think that the code that comes out of Microsoft, especially the base class library, should be built for use, reuse, extension, modification etc. Given the degree of fan-out from microsoft developers to us, it seems criminal to force people to re-implement code rather than extending of modifying it.

    If more extensible code means less code, so be it. Anyone who has worked with the BCL for more than 6 months has cursed Microsoft at some time for their sealed, private, internal or otherwise inaccessible code, I know I have.

    Clearly there are limits; but it must be possible to write a library for us that has fewer limits on it.

  30. Laszlo Marai says:

    That’s why they say that you should only inherit from abstract classes. If you plan your class to be extensible allowing the user reimplementing one or more methods, then make an abstract base class with those methods being abstract.

    If the user of your library decides to override your non abstract method, then he takes the risk of having his code break later, by a change in your code. OK, then you might ask then what’s the point in having all our methods virtual… 🙂 It’s a question of directing and enabling menthality (see, the same as with the static and dynamic/latent typing. (And the enabling approach is far from being disasterous.)

  31. Someone else having their code break is your problem how, exactly?

    Don’t worry about protecting people from themselves; all you end up doing is creating extra work for them.

  32. Thomas Eyde says:

    I see two discussions here: One is about virtual by default, the other is when/not it is safe/wanted to override/inherit something.

    It seems to me that it is not virtual by default which is harmful, but override by default. C# has neither, so there is a double protection which is definitly not necessary.

    We could have virtual by default, because we don’t have override by default. And you can’t override something which is not there.

    A compromise would be to give us the virtual class, which someone suggested. The virtual class would have all members virtual by default. In this way the decision is back where it belongs.

  33. Laszlo Toth says:

    I think alot of people have missed the hidden nugget in the original post here. GoVirtual, for example, complains ‘I don’t need MSFT running around the code libraries locking everything down "for my benefit."’ Similar thoughts are expressed all through the comments. While I agree 110% with that sentiment, I think they’re missing the evil-m$-self-interestTM. The point is that microsoft is avoiding having you override their implementations so they can go back and fix bugs without breaking your code. They’re not trying to prevent you from hurting yourself – think Outlook .pif attachments – they’re trying to prevent you from hurting THEM! Dudeman says so in the post itself:

    "It’s bad when you’d like to make a small change that would help 99.9% of your users, but you can’t because somebody might have existing code that depends on your behavior."

    It’s hard to disagree with that. Just remember: they’re only locking things down ‘for your benefit’ in the twisted sense of "what’s good for microsoft is good for you."

  34. Doug McClean says:

    I think there are two perspectives here. On the one hand, we have people used to writing code in tightly-coupled environments. They wrote the base class, they wrote the derived classes, they know the invariants, and the whole thing gets compiled at once. On the other hand, we have Eric and a few others who grok that security and maintainability in the face of runtime linking, reflection, and code access security requires testing any extensiblity scenario that you expose from a reusable library.

    Separate from this, is a few people complaining about a few instances in the FCL where the reasons why a class or method has to be sealed are non-obvious and therefore annoying to people who don’t investigate the reasons. Additionally there are a few cases where Microsoft has admitted that unsealing a class or method would work and would be a good idea, but they didn’t have enough time to test it before releasing the code. I think people should show more understanding for the fact that even Microsoft has limited resources, and that if its a choice between security/versionability/robustness and some minor speculative feature, security should win every day. You can almost always work around these issues with delegation anyway (e.g., the StreamReader example given above by James).

  35. Thomas Eyde says:

    Doug, you explain the issue very well. By now it is clear that we have two parties with non-compatible interests.

    1. The library manufacturer who needs to fix bugs without breaking existing clients,


    2. Application developers like me who has full control over the code written.

    I see the default settings favours library coders, but not application coders. I think it’s safe to assume there are more application coders than library coders. Shouldn’t the language/tool favour both?

    The defaults doesn’t hurt Microsoft, because they need them as they are. They will never feel our pain, but continue to argue why the defaults has to be what they are.

    I see possible solutions, but don’t expect to see any of them implemented:

    1. Loosen up the defaults and provide a tool to lock down everything implicit which is not used. That is, all methods are virtual by default, but the tool make all non-overridden methods final if they are not explicitly marked virtual.

    2. Get rid of the silly double protection. Why should I have to first specify virtual, then override?

    3. Leave things as is, but let the tool automaticly change the overridden method to virtual. After all, if I override a method, it is by intention. If the method is not virtual, I would change it manually. Why not let the tool do it?

    I can accept inflexible assemblies, but not inflexible source code.

Skip to main content