Article Discussion
Versioning, Virtual, and Override
Summary: Anders Hejlsberg, the lead C# architect, talks with Bruce Eckel and Bill Venners about why C# instance methods are non-virtual by default and why programmers must explicitly indicate an override.
32 posts on 3 pages.      
« Previous 1 2 3 Next »
The ability to add new comments in this discussion is temporarily disabled.
Most recent reply: November 15, 2004 0:53 PM by
Bill
Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
Versioning, Virtual, and Override
September 16, 2003 5:22 PM      
Anders Hejlsberg says, "We will never catch up. We will never fill all the capacity that Moore's law is heaping on us. The way we get more functionality these days is by doing more and more leveraging of existing infrastructure and existing applications. As systems are becoming longer lived, versioning is becoming more important."

Read this Artima.com interview with C# creator Anders Hejslberg:

http://www.artima.com/intv/nonvirtual.html

What do you think of Anders' comments?
Sakesun
Posts: 8 / Nickname: sakesun / Registered: August 18, 2003 10:00 PM
Re: Versioning, Virtual, and Override
September 17, 2003 0:40 AM      
As a long time delphi user, no wonder why I quite agree with Anders. Recently, I'm learning java. Though never have any experience in large java project, I always wonder how often does java programmer make a mistake by mis-typing the overriding method name. Without explicit "override" keyword the mis-typed method will undesireably become a new method. Also, without override it's must be very difficult to change base-class method name, since the compiler cannot help you find out where that method was overriden in the sub-classes.
Vincent
Posts: 40 / Nickname: vincent / Registered: November 13, 2002 7:25 AM
Re: Versioning, Virtual, and Override
September 17, 2003 1:42 AM      
> Also, without override it's must be
> very difficult to change base-class method name, since the
> compiler cannot help you find out where that method was
> overriden in the sub-classes.

Once a base class has been published and others have started using it then you may never have visibility of the sub-classes that others have based upon it. When that's the case, the presence or absence of a keyword such as overrides is surely acedemic.

Vince.
Sakesun
Posts: 8 / Nickname: sakesun / Registered: August 18, 2003 10:00 PM
Re: Versioning, Virtual, and Override
September 17, 2003 3:48 AM      
> Once a base class has been published and others have
> started using it then you may never have visibility of the
> sub-classes that others have based upon it. When that's
> the case, the presence or absence of a keyword such as
> overrides is surely acedemic.

Changing base-class method name can happen even on unpublished base class. C# (or Delphi) programmer can be more confident in changing method name while they are coding than java (or c++). A fancy refactoring tool can help java on this issue however.

Also, I think it's more explicit for someone reading the code later, to know which method was intend to be a new one or an overriding one.
tushar
Posts: 2 / Nickname: tusha0 / Registered: February 11, 2003 0:11 PM
Re: Versioning, Virtual, and Override
September 17, 2003 9:51 AM      
I currently work on a fairly sizable Java code base (approx. 220,000+ lines). I've seen two different defects this year caused by the signature of a virtual method being changed by the addition of a single parameter - causing the overridden methods in derived classes to be silently ignored by virtual calls :-) Scary stuff.

When you change the signature of a method, do you remember to check if there are any overridden methods that might fall off the shelf? I don't, and I don't know anyone that meticulous.

The trouble is that unless you have enough tests, you won't know about the side effects of your minor signature changes until much later. javac certainly doesn't tell you!

For this horrible reason, I've been trying to get into the habit of using Eclipse's 'Refactor->Rename', or 'Refactor->Change Method Signature' actions for every signature change :-)
Matt
Posts: 62 / Nickname: matt / Registered: February 6, 2002 7:27 AM
Re: Versioning, Virtual, and Override
September 17, 2003 9:55 AM      
Having now done plenty of C++, Delphi, Java and C#, I'd say there is no particular advantage to the more explicit inheritance mark-up in C# to offset the annoyance of extra typing and spurious (unrelated to the task I'm really working on and trying to think about) decision-making. The problems it ostensibly solves don't seem to be big ones, they are corner-cases and the solution only shifts to different problems. Conversely, I never had much of a problem in other languages with accidentally overriding base methods -- is this really such a common problem that it needs to be so aggressively tackled? Anyone else out there have experiences where this was a huge problem? Would the C# syntax have solved it?

As far as versioning goes, I thought that the side-by-side execution of assemblies was intended to solve problems arising from interface (and implementation) changes. Amusingly, the experience I've had so far with this is that the bloated, but unfortunately commonly-used, MSI installer's most common behavior shoots this feature right in the head. Usually, when you upgrade a software package, it cleverly does an uninstall+install, effectively removing all the assemblies it uses from the Global Assembly Cache, then installing the new versions; if any other compoents depend on these assemblies and didn't update the reference count (a common mistake), they are completely hosed and will unceremoniously croak on starup -- not much better than "dll hell," if you ask me. In any cases, it seems like this particular explicit stamping of a method's vituality doesn't solve the problem by any means.

Anders was complaining that in Java, designers don't use the final keyword often enough. If this is a problem, then why does C# have any default at all? Why not force the designer to declare all methods virtual or final, then there is no need for the override and new silliness. (By the way, overloading the meaning of new in this way is probably especially confusing for new (!) programmers -- I was a little confused on the meaning of using when I first started in C#, because it is likewise overloaded and used in to completely different contexts).

The only real advantage I can see to this is performance, since methods are all final by default. This helps particularly well when touting C# performance over Java's by doing little comparisions between C# and Java code speed, because most observers will fail to notice that they are comparing a C# program running final methods with a Java program running virtual methods. However, I also think that people pay too much attention to the performance effects of virtual vs. final, which I think are small compared to bigger inefficiencies that are usually just bugs in design or coding of a particular subsystem.
Geoff
Posts: 6 / Nickname: geoffs / Registered: April 24, 2003 6:15 AM
Re: Versioning, Virtual, and Override
September 19, 2003 7:48 AM      
> Anders was complaining that in Java, designers don't use
> the final keyword often enough. If this is a
> problem, then why does C# have any default at all?
> Why not force the designer to declare all methods
> virtual or final ...
> The only real advantage I can see to this is performance,
> since methods are all final by default
> However, I also think that people pay too much
> attention to the performance effects of virtual vs.
> final

I agree 100% that performance is a red-herring. However, I believe there is a very strong design reason for the explicit use of virtual and final. As Hejlsberg points out, developers do a very poor job of considering the two APIs that every class exports: 1) the "client API" (i.e. all public methods), and 2) the "extension API" (i.e. all protected and virtual methods). I personally try and keep both in mind, and find that most of my methods are public final, protected final, or some flavor of abstract. Rarely do I find the case where I need to allow a sub-class to over-ride a method (and especially, a public method) on a super-class (LSP is a hash mistress!); more often I find that the extension API is more clearly defined (and controlled) using either a protected abstract or virtual protected method (in the latter case, commonly with an empty body) in a sort of Template Method pattern sense. This gives the extension developer a specific place to alter a specific behavior of the class, while allowing the super-class to protect it's client API contract.

> ... there is no particular advantage to the more explicit
> inheritance mark-up in C# to offset the annoyance of extra
> typing and spurious (unrelated to the task I'm really
> working on and trying to think about) decision-making.
> The problems it ostensibly solves don't seem to be big
> ones, they are corner-cases and the solution only
> shifts to different problems ...

I agree. For example, Hejlsberg notes that in C#, if a new method (ex. foo()) is added to a base-class when a sub-class has already used the same name, then:

>> Now there are two virtual foos. There are two VTBL
>> slots. The derived foo hides the base foo, but that's
>> fine. The base foo wasn't even there when the derived
>> foo was written, so it's not like there's anything
>> wrong with hiding this new functionality.

This is all true if the sub-class had a virtual foo(), but what if the sub-class developer had not intended his/her foo() to be part of the extension API of the class and had correctly declared it 'final'? Similarly, what if the base-class developer did not intend the new foo() method to be part of the base-class extension API, and declared it 'final'? I can't think of a reasonable way to resolve either case other than a compile/link error. Note that Hejlsberg's argument for the desirability of 'final'ity for methods which are not explicitly part of the extension API would make it more likely that one (or both) of the above cases would occur and nothing is gained by the C# way of doing things (or worse, if some language hack silently "resolves" the problem then one is left with very confusing code).

Cheers,

Geoff Sobering
robert
Posts: 35 / Nickname: funbunny / Registered: September 23, 2003 5:08 AM
Re: Versioning, Virtual, and Override
September 23, 2003 9:12 AM      
this DbC stuff sounded familiar -> Eiffel, in fact. here's a msg posted by BM: http://groups.google.com/groups?q=%2Boutput+%2Bcontract+group:comp.lang.eiffel&hl=en&lr=&ie=UTF-8&group=comp.lang.eiffel&selm=139%40feiffel.UUCP&rnum=4

or, go to comp.lang.eiffel, search +output +contract. you'll find it. from 1995.
Robert C.
Posts: 5 / Nickname: unclebob / Registered: April 25, 2003 6:39 AM
Re: Versioning, Virtual, and Override
September 23, 2003 10:32 AM      
It never happens to me. I think if you are disciplined about writing your unit tests you'll never have this problem.
Robert C.
Posts: 5 / Nickname: unclebob / Registered: April 25, 2003 6:39 AM
Re: Versioning, Virtual, and Override
September 23, 2003 10:32 AM      
> As a long time delphi user, no wonder why I quite agree
> with Anders. Recently, I'm learning java. Though never
> have any experience in large java project, I always wonder
> how often does java programmer make a mistake by
> mis-typing the overriding method name. Without explicit
> "override" keyword the mis-typed method will undesireably
> become a new method. Also, without override it's must be
> very difficult to change base-class method name, since the
> compiler cannot help you find out where that method was
> overriden in the sub-classes.

It never happens to me. I think if you are disciplined about writing your unit tests you'll never have this problem.
Robert C.
Posts: 5 / Nickname: unclebob / Registered: April 25, 2003 6:39 AM
Re: Versioning, Virtual, and Override
September 23, 2003 10:33 AM      
> As a long time delphi user, no wonder why I quite agree
> with Anders. Recently, I'm learning java. Though never
> have any experience in large java project, I always wonder
> how often does java programmer make a mistake by
> mis-typing the overriding method name. Without explicit
> "override" keyword the mis-typed method will undesireably
> become a new method. Also, without override it's must be
> very difficult to change base-class method name, since the
> compiler cannot help you find out where that method was
> overriden in the sub-classes.

It never happens to me. I think if you are disciplined about writing your unit tests you'll never have this problem.
Robert C.
Posts: 5 / Nickname: unclebob / Registered: April 25, 2003 6:39 AM
Re: Versioning, Virtual, and Override
September 23, 2003 10:36 AM      
> As a long time delphi user, no wonder why I quite agree
> with Anders. Recently, I'm learning java. Though never
> have any experience in large java project, I always wonder
> how often does java programmer make a mistake by
> mis-typing the overriding method name. Without explicit
> "override" keyword the mis-typed method will undesireably
> become a new method. Also, without override it's must be
> very difficult to change base-class method name, since the
> compiler cannot help you find out where that method was
> overriden in the sub-classes.

It never happens to me. I think if you are disciplined about writing unit tests then it just won't happen in practice.
Robert C.
Posts: 5 / Nickname: unclebob / Registered: April 25, 2003 6:39 AM
Re: Versioning, Virtual, and Override
September 23, 2003 10:45 AM      
> I currently work on a fairly sizable Java code base
> (approx. 220,000+ lines). I've seen two different defects
> this year caused by the signature of a virtual method
> being changed by the addition of a single parameter -
> causing the overridden methods in derived classes to be
> silently ignored by virtual calls :-) Scary stuff.

What's scary is that you didn't write the unit tests that would have found that before it became a significant problem. Test Driven Development is a cure for this kind of ill.

> When you change the signature of a method, do you remember
> to check if there are any overridden methods that might
> fall off the shelf? I don't, and I don't know anyone that
> meticulous.

Do you run all the unit tests in the system after you make that change? When you do, do they catch the error? If not, why not?

> The trouble is that unless you have enough tests, you
> won't know about the side effects of your minor signature
> changes until much later. javac certainly doesn't tell
> you!

In that case the trouble is that you don't have enough tests.

> For this horrible reason, I've been trying to get into the
> habit of using Eclipse's 'Refactor->Rename', or
> 'Refactor->Change Method Signature' actions for every
> signature change :-)

Always a good idea. Eclipse or (better yet) IntelliJ provide wonderful tools for making changes like that. And tests are the way to be sure that those changes don't harm you.
Aleksander
Posts: 1 / Nickname: aslom / Registered: May 5, 2003 8:11 AM
Re: Versioning, Virtual, and Override
September 23, 2003 4:42 PM      
> As a long time delphi user, no wonder why I quite agree
> with Anders. Recently, I'm learning java. Though never
> have any experience in large java project, I always wonder
> how often does java programmer make a mistake by
> mis-typing the overriding method name. Without explicit
> "override" keyword the mis-typed method will undesireably
> become a new method. Also, without override it's must be

good IDE such as CodeGuide will indicate graphically if method is overriding existing virtual method (in CodeGuide it shows small red ball with arrow up and by cllicking it you can jump to overriden method). still i like idea of "override" keywor as it is good to have such delcarations in code so compiler and JVM can enforce it.
George A
Posts: 3 / Nickname: zgas / Registered: September 25, 2003 3:46 AM
Re: Versioning, Virtual, and Override
September 25, 2003 0:23 PM      
We have experienced the corner case where unit testing would NOT have caught the problem.

Specifically we use the Generative Pattern (code generates the base class) with externally provided meta-data. We then override the behavior in the manually coded sub-class(es) where appropriate. Since we don't write tests for all the "lame" generated code, but only the overridden methods, the fact that the meta-data was changed and the base class's method is GONE, would not be caught. In this case at least having the option of specifying that a method is "overriding" would be nice.
32 posts on 3 pages.
« Previous 1 2 3 Next »