tags:

views:

356

answers:

12

Possible Duplicate:
Why C# implements methods as non-virtual by default?

It would be much more less work to define which methods are NOT overideable instead of which are overideable because (at least for me), when you're designing a class, you don't care if its heirs will override your methods or not...

So, why methods in C# are not automatically virtual? What is the common sense in this?

+2  A: 

So it's clear whether you're allowing overriding or a method or forcing hiding of a method (via the new keyword).

Forcing you to add the keyword removes any ambiguity that might be there.

Justin Niessner
+4  A: 

Convention? Nothing more, I would think. I know Java automatically makes methods virtual, while C# does not, so there's clearly some disagreement at some level as to what's better. Personally, I prefer the C# default - consider that overriding methods is a lot less common than not overriding them, so it would seem more concise to define virtual methods explicitly.

Noldorin
+15  A: 

You should care which members can be overridden in derived classes.

Deciding which methods to make virtual should be a deliberate, well-thought-out decision - not something that happens automatically - the same as any other decisions regarding the public surface of your API.

LukeH
And I'm no longer typing my answer, because it was essentially a more wordy version of this. +1.
John Rudy
The Java guys clearly didn't agree with you... though I think I would.
Noldorin
+1 Yes, once you make something virtual, you have alot more scenarios to consider when thinking bout how your class will be used by others, and this adds to design, implementation, and testing complexity.
AaronLS
So from what you are saying, classes should be sealed by default. Why they're not?
TTT
@Alon: Yes, I do think that classes should default to being sealed. Why aren't they? I don't know.
LukeH
Well, if even Eric Lippert of the C# dev team knows, I guess it's a mystery to the ages. (He came after 1.0 shipped, mind you)(Reference: http://blogs.msdn.com/ericlippert/archive/2008/04/24/why-can-t-i-access-a-protected-member-from-a-derived-class-part-three.aspx)
Kyte
I disagree. If you are following composition over inheritance, your classes should be very straight forward (but there will be a lot of them) If your classes are straight forward, having everything open to extension makes things more flexible. (This is why C# is such a pain to mock compared to java). IMO proper method/object construction takes most of the risk away, at least enough where the gains no longer outweigh the costs.
Matt Briggs
@Matt: And if your classes are well-designed and straightforward then there's nothing to stop you making all their members virtual. Defaulting to non-virtual just helps to mitigate the risk that an entire hierarchy of classes gets broken by changes in a badly designed base class.
LukeH
@Luke: granted, but there are some side effects to making it virtual by default. First, the runtime needs to be really great at optimizing for them (you see that with virtual and exceptions. in java, they are fast cause they need to be, in C# they are both very expensive). Secondly, as soon as you start talking about mocking (or doing anything with a dynamic proxy), your options get more limited, since people are only going to mark methods as virtual if they think of it, even if having the method be virtual wouldn't have a negative impact.
Matt Briggs
also, I understand this has a lot to do with style and taste, and not really trolling so much as trying to present the other side of the argument, which tends to be under-represented in C# circles :-)
Matt Briggs
+5  A: 

Beyond the design and clarity reasons a non-virtual method is also technically better for a couple of reasons:

  • Virtual methods take longer to call (because the runtime needs to navigate through the virtual lookup table to find the actual method to call)
  • Virtual methods can't be inlined (because the compiler doesn't know at compile time which method will eventually be called)

Therefore unless you have specific intentions to override the method it is better for it to be non-virtual.

Martin Harris
A: 

Actually, that's bad design practice. Not caring which methods are override-able and which are not, I mean. You should always think about what should and should be override-able just as you should carefully consider what should or shouldn't be public!

Miky Dinescu
+1  A: 

I believe there is an efficiency issue as well as the reasons others have posted. There is no need to spend the cpu cycles to look for an override if the method is not virtual.

Ray
A: 

When someone inherits from your class, that would give them the ability to change how any method works when the base class uses it. If you have a method that you absolutely need it to perform an action a certain way in the base class, you would have no way not allowing someone to change that functionality.

Here's one example. Suppose you have a function that you expect to not return an error. Someone comes in and decides to change it so that on Tuesday, it throws an out of range exception. Now the code in the base class fails, because something it depended on happening changed.

Kevin
A: 

Because it's not Java

Seriously, just a different backing philosophy. Java wanted wanted extensibility to be the default and encapsulation to be explicit and C# wanted extensibility to be explicit and encapsulation to be the default.

Dinah
+18  A: 

Anders Hejlsberg answered that question in this interview and I quote:

There are several reasons. One is performance. We can observe that as people write code in Java, they forget to mark their methods final. Therefore, those methods are virtual. Because they're virtual, they don't perform as well. There's just performance overhead associated with being a virtual method. That's one issue.

A more important issue is versioning. There are two schools of thought about virtual methods. The academic school of thought says, "Everything should be virtual, because I might want to override it someday." The pragmatic school of thought, which comes from building real applications that run in the real world, says, "We've got to be real careful about what we make virtual."

When we make something virtual in a platform, we're making an awful lot of promises about how it evolves in the future. For a non-virtual method, we promise that when you call this method, x and y will happen. When we publish a virtual method in an API, we not only promise that when you call this method, x and y will happen. We also promise that when you override this method, we will call it in this particular sequence with regard to these other ones and the state will be in this and that invariant.

Every time you say virtual in an API, you are creating a call back hook. As an OS or API framework designer, you've got to be real careful about that. You don't want users overriding and hooking at any arbitrary point in an API, because you cannot necessarily make those promises. And people may not fully understand the promises they are making when they make something virtual.

John
+1  A: 

See also the answer of Anders Hejlsberg (the inventor of C#) at A Conversation with Anders Hejlsberg, Part IV.

Daniel Rose
+1: this is a great interview!
Dinah
+1  A: 

To paraphrase Eric Lippert, one of the guys who designed C#: So you code doesn't get accidentally broken when the source code you recieved from a third party is changed. In other words, to prevent the Brittle Base Class problem.

If a method is to be virtual, if because you (supposedly) made the conscious decision to allow the function to be replaceable, and designed, tested and document around that. What happens if, say, you made a function "frob" and, in some subsequent version, the base class's makers decide to also make a function "frob"?

Kyte
+1  A: 

There are always two approaches when you want to specify that you are allowing or denying something. You can either trust everyone and punish sinners or you can distrust everyone and force them to ask permission.

There are some minor performance problems with virtual methods - can't be inlined, slower to call than non-virtual methods - but that really isn't that important.

More significantly they pose threat for your design. It's not about caring what others will do with your class it's about good object design. When a method is virtual you are saying that you can plug it out and replace it with different implementation. As I say you must treat such a method as an enemy - you can't trust it. You can't rely on any side-effects. You have to set up very strict contract for that method and stick with it.

If you consider that human is very lazy and forgetting creature which approach is more prudent?

I have never personally used virtual method in my design. If there is some logic that my class uses and I want it to be interchangeable then I just create interface for it. That interface than constitutes above mentioned contract. There are some situations where you really need virtual methods but I think that those are quite rare.

CodeRipper