Reputation: 33398
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.
Upvotes: 10
Views: 6164
Reputation: 29222
For clarity, if that happens, I use ClassV2.
That indicates that it's another version of the class.
Upvotes: 2
Reputation: 244782
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.
Upvotes: 19
Reputation: 95
I think duplication class name will seriously confuse other people overtime. You extract method with c# interface and implement different version.
Upvotes: 2
Reputation: 149538
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".
Upvotes: 4
Reputation: 37000
I would copy all the behaviour of your existing class to a new one, rename the original one to indicate that the class is obsolete, rename the new one to the actual name from before and mark the original one (with the new name now) as [Obsolete]
indicating that it should not be used any more. Thus all consuming code automatically invokles the new behaviour. So your new class with the correct behaviour gets the name of the original class, where the buggy one gets a version-number for instance.
For legacy code you can do the opposite, make a new class with new name and mark the old one as Obsolete
. I know SDKs with a version-number, where the last number indicates the most recent version of the class, and all the others have such an attribute together with a notice within the docs mentioning that the class is superseded with a new version.
Upvotes: 3