I have a class MyClass
which has a bug in the implementation. The class is part of a library, so I can't change the implementation of the class because it will silently change behavior for existing clients (clients who in this case may rely on the bug: See for example (https://connect.microsoft.com/VisualStudio/feedback/details/790160/httpclient-throws-operationcanceledexception-insead-of-timeoutexception))
I need to create a second version of the same class which includes the bug fix.
I've seen situations like this before but the naming I've seen was always incremental Eg MyClass2
, MyClass3
.
These cases are probably quite rare, however I was wondering if there is a better way of naming these "versioned" classes.
I imagine a solution which grows in time and has multiple classes of these type which can get probably really confusing especially for a library. I imagine myself having to pick between MyClass
, MyClassV2
, MyClassV3
etc.
Class names should be nouns, in mixed case with the first letter of each internal word capitalized. Try to keep your class names simple and descriptive. Use whole words-avoid acronyms and abbreviations (unless the abbreviation is much more widely used than the long form, such as URL or HTML).
A file naming convention is a systematic method for naming files that will make them easier to retrieve later. A consistent and descriptive convention will allow you to: Know the content of a file without opening it. Find and identify files even if they are no longer in their original folder.
Classes should be named with an uppercase letter, and be concise, for example Customer or Product. Method names begin with a lowercase letter, with subsequent words in uppercase. They are actions and should be verbs. Examples include getCustomerName() or updatePayTable().
In an ideal world, new versions would introduce additional functionality while still remaining 100% backwards compatibility with previous versions of the API. Unfortunately, the ideal world remains elusive, and it is not always possible to retain full backwards compatibility. A versioned suffix is the appropriate pattern in this case.
The standard .NET naming convention is to use incremental numbering, like Class
, Class2
, Class3
, etc.. This comes from the naming convention for COM interfaces, designed for exactly the use case you're describing. For example, the IHTMLDocument
interface currently has 8 versions, from IHTMLDocument
up through IHTMLDocument8
.
The original Framework Design Guidelines book, by Cwalina and Abrams, explicitly recommended this practice, with the authors having this to say:
DO use a numeric suffix to indicate a new version of the existing API, if the existing name of the API is the only name that makes sense (i.e., it is an industry standard), and adding any meaningful suffix (or changing the name) is not an appropriate option.
// old API [Obsolete("This type is obsolete. Please use the new version of the same class, X509Certificate2."] public class X509Certificate { ... } // new API public class X509Certificate2 { ... }
The old convention, followed by the original Windows team, was to add the suffix Ex
to new-and-improved versions of an API, which comes from the word "extend." This doesn't scale well, however, leading to functions confusingly suffixed ExEx
. I don't think there was an ExExEx
; everyone was afraid to touch those APIs. The Framework Design Guidelines recommend explicitly against this practice, the folks who went on to architect .NET having learned their lesson:
DO NOT use the "Ex" (or similar) suffix for an identifier to distinguish it from an earlier version of the same API.
[Obsolete("This type is obsolete. ..."] public class Car { ... } // new API public class CarEx { ... } // the wrong way public class CarNew { ... } // the wrong way public class Car2 { ... } // the right way public class Automobile { ... } // the right way
Obviously, as their last code sample hints, if you are adding support for a specific feature in the new version of the API, you would be best off naming the new class/interface with a reference to that particular feature.
And although the above has focused almost exclusively on classes and interfaces, the same logic would hold true for any member functions of that class that might be added in later revisions. The original function could retain its original name, with the newly added function having a different name that either reflects its iteration or its added functionality.
I was wondering if there is a better way of naming these "versioned" classes.
There is no .NET naming convention for "classes which fix bugs in other classes". I would advise with other developers in your workplace and see if they have any company conventions for such a thing. I think consistency is of importance more than the actual name.
And on a side note to your problem, I wouldn't create a new class at all. I would mark the method with DeprecatedAttribute
and implement the logic inside the same class, exposing a new set of API methods which are properly documented to state they are here as a fix. The clients of your library are probably already familiar with MyClass
, and doing so would ease the use for them, interleaving them the need to ask themselves each time "which version of this should I use".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With