"virtual" method call performance
After my post yesterday on the C# Coding Standards document, I received a comment from Adam with relation to the performance of the calls. There's a common misconception about how virtual should be used, and I wanted to address the perf issue here. (Comments are here and here.)
Brad Abrams has a superb set of .NET Design Guidelines, which can found on his GDN blog here. He's been kind enough to cut-and-paste sections from internal design documents that the Microsoft dev teams use themselves. One of these (Subclassing Usage Guidelines) speaks about this issue in some detail.
Rather than cut and paste the whole thing, I've edited out some that I think are particularly salient:
Do minimize number and complexity of virtual members in your APIs. Virtual members defeat some performance optimizations the runtime provides and could “box-in” your design.
Do not use virtual members unless you have specifically designed for specialization:
You have a concrete extensibility scenario in mind.
You have written a quality sample demonstrating the extensibility scenario. Preferably the sample should be done by a “3rd party” to independently validate the design.
You have clearly documented contracts of all virtual members.
Do think twice before you virtualize members:
Annotation - The peril. If you ship types with virtual members you are promising to forever abide by subtle and complex observable behaviors and subclass interactions.
I think API designers underestimate their peril. For example, we found that ArrayList item enumeration calls several virtual methods per each MoveNext and Current. Fixing those performance problems could (but probably doesn't) break user-defined implementations of virtual members on the ArrayList class that are dependent upon virtual method call order/frequency.
FxCop Rule (draft): Flag non-sealed public types that introduce virtual members with the message: “Virtual members represent points of specialization in your type. Great care should be taken in exposing virtual members, please see the design guidelines document on this topic and fully consider the ramifications.”
Consider designing classes with inheritance scenarios in mind and appropriate virtual members.
Doing this correctly requires a careful specification outlining the exact contract of all the virtual members. It is strongly suggested that you create at least one subclass ideally in the shipping product. Although this is the ideal, it is somewhat costly.