Rationale for Generic Type Parameter Naming Guidelines

The recent type parameter naming guidelines update resulted in a very lively discussion. I thought I would provide some rational for the recent changes.

But first, I would like to first thank all of you who got involved in the debate. We have had debates like that for ages about many issues related to our products, but they were mostly happening behind the scenes. It’s great to have the community in these discussions now.

Thanks!

Rationale for Generic Type Parameter Naming Guidelines

  1. Single letter type parameters are completely fine for simple types like List<T> where T can be anything and there is only one type parameter. Once you have more than one parameter or T cannot be any type (for example it’s constrained), the convention is not that great anymore (Converter<T,U> would be an example).
  2. Tools could help (not solve the problem completely), but we have a general philosophy of trying to solve problems without tools support and then only if it’s not possible, we think about tool based solutions. There are several reasons for it. Many people don’t use VS to program Framework apps. Secondly, you can only solve a limiter number of problems with tools; when you try to solve too many problems with tools, the different features of the tool start to get into each other way. Thirdly, tool based solutions to problems are never as clean as not having a problem in the first place (see Design of Everyday Things). And lastly, tool based solutions don’t work for reading code printed on paper, books, MSDN, email, etc.
  3. Tools work pretty well for scenarios where one uses a generic type (as noted in many comments). They don’t work great for people creating or extending generic types.
  4. We got lots of feedback from people who have written extensive libraries (10x the BCL collections package) using generics. They showed us that the single letter convention simply breaks once you have several interrelated generic types, as opposed to dealing with one or two generic types at a time (for starters try writing a generic type with another nested generic type and use T for both). In large systems of multiple generic types, you simply get lost in the myriad of Ts, Ks, and Vs.
  5. We believe that as people will start to write more code using generics they will start to appreciate the new naming conventions. If we left the conventions as they were, initially people would be happy with them, but then they would run into the issues described above and wish we used long names. I realize that this is speculative, but we are just trying to do our best to guess the future based on some limited data points we have (a few people who hated the long names and completely changed their mind after using them in large projects).
  6. Now, some rationale for the “T” prefix: There are differences in what one would consider a good type parameter name depending on whether one uses a generic type or writes/extends a generic type. Parameters without a naming convention differentiating them from regular type names are fine in simple usage scenarios of generics (like instantiating List<T>) and in a bit more advanced scenarios (like instantiating EventHandler<T>) with the help of tools/intellisense. They don’t work as well for people creating or extending generic types and for reading snippets of code taken out of the context of the full type definition (where you don’t see the < > brackets). Basically when you deal with a member (method for example) using a generic parameter declared on a type (not on the method), names like Key, ValueType, FooKind, etc. all appear as if they were real types. Only the context of the brackets can make it clear what they really are, but the context is often lost when working far away from the type declaration.