In an ideal world, new versions will introduce additional features while maintaining 100% backward compatibility with previous versions of the API. Unfortunately, an ideal world remains elusive, and it is not always possible to maintain full backward compatibility. The suffix with the version is a suitable pattern in this case.
The standard .NET naming convention is to use incremental numbering like Class , Class2 , Class3 , etc. This comes from a naming convention for COM interfaces designed specifically for your use of the description. For example, the IHTMLDocument interface currently has 8 versions, from IHTMLDocument to IHTMLDocument8 .
In the original Wireframe Design Guide, the book by Qualina and Abrams explicitly recommended this practice when the authors said the following:
DO use a numeric suffix to indicate a new version of an existing API if the existing API name 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 a suitable 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 Ex suffix to new and improved versions of the API, which comes from the word "extend." However, it does not scale very well, which leads to confusing ExEx functions. I do not think that was ExExEx ; everyone was afraid to touch these APIs. Framework design guides explicitly recommend against this practice, people who went to the .NET architecture after learning their lesson:
DO NOT use the βExβ suffix (or similar) for an identifier to distinguish it from an earlier version of the same API.
[Obsolete("This type is obsolete. ..."] public class Car { ... }
Obviously, since their latest code example tells you if you add support for a particular function in the new version of the API, you would be better off not calling the new class / interface a reference to that particular function.
Although the above focuses almost exclusively on classes and interfaces, the same logic will be true for any member functions of this class that may be added in future versions. The original function can retain its original name, and the newly added function has a different name that either reflects its iteration or its added functionality.