다음을 통해 공유


Naming generic type parameters...

There's been quite a discussion going on on the MSDN feedback site over the naming of generic type parameters.

If you look at the definition of the generic collections classes, you'll see things like:

List<T>
Dictionary<K, V>

What's up with those T's, K's, and V's?

If you look at our beta1 library design guidelines (can't find a published link right now) that suggests that you use single-character names for type parameters rather than longer, more descriptive names. But those guidelines weren't always there. In fact, before we had them, you might see a class like:

class Dictionary<Key, Value>
{}

which seems reasonable enough. But one day, you're browsing code, and you look at a method:

public void Process(Key k)
{
    // code here...
}

What's Key? It looks like it's a type, and unless you know that there's a type parameter named “Key“, you're likely to be confused for a while. We therefore decided to use the single-character naming approach, and my experience is that it's worked pretty well.

When you're working on a generic class, you normally have a small number of generic type parameters, and therefore it's not that hard to keep them straight. When you're using them, C# intellisense is nice enough to give you a description for the type parameter so you remember what it is.

That is, it's nice enough to do that if you remember to *write* the description using the <typeparam> tag. The IDE will add this tag automatically when you type the /// before your generic class definition.

Unfortunately, the beta1 drop doesn't have these descriptions for the built-in collection classes, so you don't get any help right now if you type “List<“. We'll be fixing that.

Comments

  • Anonymous
    July 16, 2004
    This really struck me as odd too. I disagree with the T, K, V naming convention.

    Yes, it will look like a data type, so why not just use a descriptive name? Perhaps:

    class Dictionary<GEN_A, GEN_B, GEN_C>
    {
    public void Process(GEN_A genValue, GEN_C genObject)
    {
    // code here...
    }
    }

    If that were the "standard", it would be clear that when you are working with a GEN_ "data type", it's a generic.

  • Anonymous
    July 16, 2004
    Hmm...
    Then maybe we should write:

    public class CLASS_Button { ... }
    or
    public struct STRUCT_Point { ... }
    or
    public interface INTERFACE_IComparable...
    or
    public void METHOD_Process() { ... }

    Prefixing rather has no sense...
    In my opinion "single letter" is OK :-)




  • Anonymous
    July 16, 2004
    I think the single letter convention is great. That's already the standard for most of all C++ template classes. If a strong, working convention already exists, why not embrace that?

  • Anonymous
    July 16, 2004
    Click on the word "Key".
    Press F12.
    Know. :)

  • Anonymous
    July 16, 2004
    "When you're using them, C# intellisense...."

    Remember C# doesn't give me intellisense the IDE does. This does nothing for Don when he is using emacs, [if he still is].

  • Anonymous
    July 16, 2004
    Voytek, generics are clearly a different kind of thing should be handled differently.

    but Sebmol, good point...

  • Anonymous
    July 16, 2004
    The comment has been removed

  • Anonymous
    July 16, 2004
    Mark,

    This not a c# issue. It doesn't go in the spec. It's just a recommendation from Microsoft, who happen to own IntelliSense. ;)
    If you don't use the VS IDE, just use your own notation. I think I'll stick to 'long' names because everyone I know uses VS and I think they're just better. :)

  • Anonymous
    July 16, 2004
    I wrote this already in other words in the feedback thread, by take on this issue is as follows.

    I agree with the single letter type names, and Eric's argument that these names make them more recognizable is the best argument indeed.

    What some people seem to forget is that there are two roles for users of generic classes: the 'Writer': the programmer who is writing (and documenting) the class and the 'Consumer'; the programmer who uses the instanced classes.

    For these two roles, the way the template type names ('T', 'K', 'V', etc.) are viewed is different. The discussion may become more clear if you look at it from a distance and see that the goals of these roles are not the same.

    The 'writer' will actually use these type names. He will like a clear way to distinguish those types from anything else he is writing, and using single-letter names is a great way to achieve that goal.

    For the 'consumer' the documentation that comes with the class is more relevant than the actual source (at least: that should be the case). Here I consider 'documentation' to be both the actual documentation (e.g. generated from XML comments) and the public API of the type. I can imagine that people who look at it from this way prefer to see more descriptive names.

    I think that the <typeparam> tag mentioned by Eric (this is the first time I hear about it) goes a long way in bridging the gap between these two views. Of course, this assumes access to an IDE that will actually show those tags in Intellisense, and won't help people who prefer to do their coding in Edlin...

  • Anonymous
    July 16, 2004
    The comment has been removed

  • Anonymous
    July 16, 2004
    I just noticed that the proposed solution of the issue ticket on the msdn site (the first link in the post) is the same as my idea above with the exception that T is added as a suffix instead of a prefix to the name:

    <blockquote>
    Use mnemonic names for parameterized types throughout the documentation, instead of meaningless single letters. To be more specific, use the descriptive-name-with-suffix-T convention (e.g. ItemT, KeyT, ValueT, FromT).</blockquote>

  • Anonymous
    July 16, 2004
    If the IDE can succesfully differentiate generic placeholders from other names, then theres no probelm whatsoever.

    Failing that, I suggest ALL CAPS for the gernic placeholders.

    Dictionary<KEY,VALUE>
    public void Process(KEY k)

  • Anonymous
    July 16, 2004
    I'll add my vote for using T either as a prefix (TKey, like IComparable) or a suffix (KeyT) for generic type parameters. Either is better than the single-character names. Suffixes read more naturally if you mentally expand the T to "type" - "key type" etc. However, hat logic would also apply to IComparable, and there's value in consistency too. If pushed, I'd go for suffixes; it's just a gut feeling, but I think the distinction from regular types would be clearer to me that way.

    I agree with a poster above who pointed out that a language-level rather than IDE-level solution is appropriate here. I love what the IDE does for me (VS.NET is the first IDE to make me feel that way, incidentally) but I'd hate to be dependent on it for something like this. We might as well start naming all our variables v1, v2, v3 and rely on the doc-comments and mouseovers to know what all of them are...

  • Anonymous
    July 16, 2004
    Typo: "hat logic" - should be "that logic" of course. "Hat logic" sounds like what the teacher from South Park uses...

  • Anonymous
    July 16, 2004
    T stands for Template, from C++ templates. So .Net version should use G, for generics as a generic type prefix.

    And yes, generics are the same as C++ templates, they're just not called templates. And C++ templates can actually do more than generics (template parameters can be just that, parameters, they don't have to be types).

  • Anonymous
    July 16, 2004
    The comment has been removed

  • Anonymous
    July 16, 2004
    The comment has been removed

  • Anonymous
    July 16, 2004
    ok -

    a) ALL prefix-based conventions are bad. We learnt the painful way with hungarian, lets not make the same mistake again. For example, even the very poor IBlah convention - how many times have you replaced a concrete class with an interface? Should the consumer of your class care? They call a factory, get an object back - it's none of their business whether they are dealing with a class or an interface! - just lots of rewriting to do if you wanna stick to a poor convention. I've also seen databases with every Table prefixed T, and every view prefixed V. Let's wake up and remember our sanity!

    b) people are ignoring what Omer has said - but it's quite right - if you really "want to know" - you can easily find out...

    however - on that...

    c) every time you USE a template, you will see code like

    > Blah<int, string> x = new Blah(10, "hello");

    you WON'T see the template parameter names. The only place you will see template parameters is in the template code itself. You should be aware that you are looking at a templated class, and the parameters when you open the class - they are at the top of the screen! but really, it shouldn't really matter. If you see

    > void Add( Blah theKeyToAdd ) {_internalList.Add( theKeyToAdd );

    you understand the intent of the function, and if you need to fix it, you can - you DON'T need to know immediately that it is a templated or a concrete type...

    d) If you DO really want to know immediately, there is a perfect an obvious solution readily apparent - colour syntax highlighting - template parameters appear in a different colour - easy - obvious, and doesn't require developers to have followed one of many "standard" conventions.

    e) but the most important reason that template parameters must be named properly is always for the developer. You've made your ClassCopier<A,B> function. You made it years ago. You have to put in a new CopyAndLog function on it.. hmmm... now is A the source or the destination? do we copy from A into B? or do we take B and store it in A? who knows? Now, suppose the function was named ClassCopier<destinationType, sourceType>. Gee... now it's easy!

    We should be writing code for readability, reliability and maintainability, and meaningless template paramaters fail on all counts. The one tiny advantage (that is that they are immediately recognizable as template parameters) is easily replaced by a better cue (ie colour), should be obvious from the name of the template parameter anyway, and finally, IS NOT ACTUALLY IMPORTANT for the reader to know, when they are first reading through the code!

  • Anonymous
    July 16, 2004
    It will be interesting to see what you guys do with the feedback now. It's apparent that you've had a discussion internally and decided to make those changes toward T, K, V. You even state that you find it works well. So we know your opinion.

    However, the comments at the feedback center are overwhelmingly in favor of more descriptive names. Now you know our opinion.

    Will you be able to change your mind based on this feedback, or is this whole thing all for show?

    Don't get me wrong, I really like to see Microsoft opening up a bit, the blogs, Channel9, all that stuff. I also understand that the people doing all the hard work will always have a disproportionate say in those decisions (and rightly so! not everything has to be democratic). But the suggestion was put up there on your own feedback center and publicised by yourself, and now a majority of people who took the time to provide feedback want more decriptive names.

    The ball is in your camp.

    For the tally, my lowly opinion on the matter is that T is fine for collections, K and V for dictionary collections is stretching it a bit, and for everything else it should be plain un-adorned descriptive names. That means List<T>, Dictionary<Key, Value> (or maybe Dictionary<K, V>) and Convert<To, From> for example. My reasoning is that T for collections is already well-established as a convention in C++ so it's ok, but in general things should be self-documenting as much as possible; just as you wouldn't have Console.Write(string m), you shouldn't have single-letter generic parameters.

    In any case, thanks for listening!

  • Anonymous
    July 16, 2004
    The comment has been removed

  • Anonymous
    July 17, 2004
    I'm fine with the single letter parameters, but it'd be nice if you also set up some official guidelines for the naming, like T is type, K is key and V is value currently. I can't think of more yet, since I'm happy with T,K and V in my own types.

  • Anonymous
    July 17, 2004
    I'm willing to go with whatever most people are using, but I just want to say that it makes me sad that .NET programmer are even considering prefixes. In a perfect world, people who use anything even vaguely Hungarian, including m_ on private fields, would be shot in the face. I just wish people would realize the the problem isn't what we name the parameters; the problem is the horrid angle-bracket syntax we're forced to use.

  • Anonymous
    July 18, 2004
    I'm with Stuart and Quaid on this one. My preference would be a "Type" suffix that spells it out (e.g. KeyType).

    Having used templates quite a bit in C++, I'm not in favour of the single letter approach, no matter how accepted it may be :-). I find that declarations that use the type parameter can be particularly difficult to read correctly first time.

    I'm not generally in favour of the Hungarian-style approach to naming variables, but I think there are a few cases where some meta-information in the variable names is useful. Identifying types as being types is one of those cases.

  • Anonymous
    July 18, 2004
    It occurred to me that there are at least two precedents in the .NET framework for a suffix-based convention.

    IOException, SocketException, DataException, ...
    SerializableAttribute, IndexerNameAttribute, ...

    (the latter convention is even supported at the language level)

    I think both of these examples are more relevant than the "IFoo" convention because they are almost never (as far as I've seen, anyway) criticized as "hungarian-like". They're so obvious and understandable that nobody thinks of them in that way. So not all suffix-based conventions are bad.

    My reason for preferring KeyT to KeyType is that if you read "KeyType k = something" it sounds like k is a "type of key" (enum KeyType {Brass, Gold, Silver, StainlessSteel}?), when in fact it actually is a "key". We want something that reads as naturally as "Key k = something" - where it's clear that k is a Key - but still makes it clear that the type of "k" is something special. Sorry if this paragraph is a bit hard to follow - I can't think of a way to express it more clearly. Talking about types of types clearly is hard :)

  • Anonymous
    July 18, 2004
    The comment has been removed

  • Anonymous
    December 27, 2004
    [http://itpeixun.51.net/][http://aissl.51.net/][http://kukuxz003.freewebpage.org/][http://kukuxz001.51.net/][http://kukuxz003.51.net/][http://kukuxz005.51.net/][http://kukuxz002.51.net/][http://kukuxz004.freewebpage.org/][http://kukuxz007.51.net/][http://kukuxz001.freewebpage.org/][http://kukuxz006.51.net/][http://kukuxz002.freewebpage.org/][http://kukuxz004.51.net/][http://kukuxz008.51.net/][http://kukuxz009.51.net/][http://kukuxz005.freewebpage.org/][http://kukuxz006.freewebpage.org/][http://kukuxz007.freewebpage.org/][http://kukuxz009.freewebpage.org/]

  • Anonymous
    May 31, 2009
    PingBack from http://woodtvstand.info/story.php?id=2643

  • Anonymous
    June 08, 2009
    PingBack from http://hairgrowthproducts.info/story.php?id=1371

  • Anonymous
    June 09, 2009
    PingBack from http://toenailfungusite.info/story.php?id=3287