Freigeben über


OK, I give. Here are a set of internal coding guidelines

We had a great chat today following up from the Designing .NET Class Libraries session on Naming Conventions. I believe we did get a transcript of that chat that will be posted soon. One of the things that was asked in one way or another about 50 times was around a style guide for implementation details of your frameworks. I have thus far resisted going there as I have found the religious wars not worth the cost as my core goal is to ensure a consistent 3rd party developer experience, so stuff like bracing style and tabs vs spaces don’t mater.

That said, I was convinced during the chat that there is value in offering a standard set of guidelines for folks to reference. I post them here in the hopes that it saves your development team time… Hopefully by using these guidelines as tie breaker you will have fewer arguments internally and get more real work done.

But before the flames start, I want to be clear; these are NOT iron-clad guidelines that everyone at MS follows… In that sense they do carry less weight than the other design guidelines I talk about here regularly. Also, I am sure there are some suggestions to making them better, cleaner. I will entertain those in the spirit of improving the doc, but my first priority is still the public surface area…

Enjoy.

Internal Coding Guidelines

Comments

  • Anonymous
    January 26, 2005
    The only thing there that I really disagree with is not prefixing private member variables with an underscore.

    Using a single underscore is much shorter and easier than using a (optional) this. prefix to differentiate between parameters and private variables in code and has the nice added benefit of grouping the private variables together, allowing for quick browsing using the intellisense dropdown.

    My 2c.

  • Anonymous
    January 26, 2005
    But a single underscore in front is plain _ugly.

    (Oh, I am coming close to the CamelCase vs under_scores flamewar here, better be careful nowg)

    I agree its good for reading to have all internal variables begin with the same prefix (recommended reading: John Lakos, 'large scale c++ programming'), but a single underscore is sometimes easily missed and, uhm, well, looks plain ugly to me :)

    Sam

  • Anonymous
    January 26, 2005
    I guess it is a little ugly but I find it preferable to having lots of this.'s throughout my code, bloating it unnecessarily, when a single character could do.

  • Anonymous
    January 26, 2005
    The comment has been removed

  • Anonymous
    January 26, 2005
    Sam you are contradicting yourself. Either an underscore is easy to miss or it is ugly.

  • Anonymous
    January 26, 2005
    RJ, You think so?

    When I read source from someone else (e.g. codeproject) I tend to miss leading underscores when they are used in compact source - when I see them, usually where they are defined, or at a closer look at the complex source (that made no sense without the closer look since I missed the leading underscore), then I see the underscore and it looks ugly to me.

    (btw, m_ also looks ugly to me, but it aint so easy to miss.)

    I see no connection between 'easy to miss' and 'ugly'. Something can be one, both, or naught of this.

    Maybe you can explain to me where the contradiction is?

  • Anonymous
    January 26, 2005
    The comment has been removed

  • Anonymous
    January 26, 2005
    Brad,

    I was in the chat yesterday but did not get a chance to voice my question (had to leave).

    The single worst parameter name I have ever seen in my life is:

    Control.Dispose(bool disposing);

    Yuck!! What on earth does that parameter mean? DON'T answer the question - that's not the point. The point is there is NO way to fathom what on earth a "disposing" bool parameter means to a method called "dispose" without looking at the help. And of course I need to look at the help all the time cause I can't be sure remember correctly.

    Are you going to fix this ghastly atrocity somehow? Please say that you are.

  • Anonymous
    January 27, 2005
    The comment has been removed

  • Anonymous
    January 27, 2005
    You're all wrong. All private members should be prefixed with:<br><br>thisVariableIsPrivate_<br><br>It has both the benefits of using &quot;this&quot; and _ and is very clear in the meaning. Much more so than such arcane symbols as &quot;m_&quot; and &quot;_&quot;.

  • Anonymous
    January 27, 2005
    Hey, cool! Each of your spacing suggestions addresses a pet peeve of mine. And all this time, I thought I was being stubborn with refusing to adopt some of the older C-style conventions.

  • Anonymous
    January 27, 2005
    You're all wrong. All private members should be prefixed with: thisVariableIsPrivate_ It has both the benefits of using "this" and _ and is very clear in the meaning. Much more so than such arcane symbols as "m_" and "_".

  • Anonymous
    January 27, 2005
    Using some form of decoration on instance variables is beneficial in my opinion. The problem with using this is that the compiler will compile up the resulting code just fine if you forget to apply "this.". Then the resulting code is harder to read because I can't easily disambiguate between local, instance and static variables. We currently recommend using m_ for instance variables and s_ for static variables. In this case, forgetting the "m_" later on doesnt' work because the code won't compile. However I find myself starting to like the simpler "_" approach but then what do I do to know if a var is a static? I am also starting to long to use the all caps naming convention for non-public constants e.g. private int BUFFER_SIZE;

  • Anonymous
    January 27, 2005
    Totally agree about the Dispose method's parameter name "disposing". Surely "notFinalizing" or "isNotFinalizing" would have been easier to understand?

    It's a shame MS didn't follow their standards for their templates - the Form template clearly violates the guidelines for spacing.

    More annoying is the space that VS puts between the method name and the parenthesis when you overload a method: "base.Something ();"

    I think those last two points are fixed one way or another in Whidbey... although I still think "disposing" is a rotten name for the parameter.

  • Anonymous
    January 27, 2005
    The Internal Coding Guidelines posted by Brad Abrams are very similar to the style I prefer. Perhaps the main difference is that I use an underscore prefix for member variables, although I've never been completely happy with this. It does...

  • Anonymous
    January 27, 2005
    I think the "lack of prefix for member variables" idea is being misunderstood. It is not that you use "this." all the time as a replacement for "m_". You only need to use "this." when you run into the rare situation where a method parameter name matches the name of a member variable. In my experience, this only happens in constructors, because in property set methods the incoming value is always named "value".

    So in practice the "lack of prefix" convention works just fine, and is not difficult to read. We use this convention.

    At first I found it hard to read, as I was used to the m_ prefix from C++. Later I realized it could only become a problem with constructors, and when looking at a single very long method extracted from a class. In the latter case, you do not have the class definition in front of you to define the member variables, and the length of the method means one may forget the names of the incoming parameters when browsing the depths.

    Even with this drawback, I now prefer no member prefix, as it is both easier on the eyes and the wrist.

  • Anonymous
    January 28, 2005
    Matt, I totally agree on the protected Dispose bool parameter. I should have been called something like disposedManaged.
    Frank, removing the prefixes for ivars is probably something I could get used to. It is just so ingrained. Although I do like the advantage of having all ivars grouped together in the Intellisense drop down list. Of course, that could be accomplished without relying on lexigraphical sorts but MS would have to implement that support.

  • Anonymous
    January 28, 2005
    I pefer non-prefixed class and local variables. 90% of the time the appropriate scope is obvious from the variables name. For the remaining 10%, we have intellisense.

    The point that is so often missed is that pronouncable code is readable code, even when reading silently. (For a great read on how things so seemingly innocent as underlines and boldface can destroy the reading experience, I recommend Bill Hill's The Magic of Reading)

    Code is read far more often than its written. There has been a lot of research on what makes things easy to read, and professionals ought to at least consider what has come before.

  • Anonymous
    January 30, 2005
    I preferred http://www.tiobe.com/standards/gemrcsharpcs.pdf

  • Anonymous
    January 31, 2005
    I agree entirely that 'protected void Dispose(bool disposing)' isn't a great method signature... for a number of reasons. IMHO, the primary problem is more to do with the name of the method itself.

    One could imagine a world where 'Dispose(bool)' is formalized as the "destructor" and had been given C#'s syntax (instead of Finalize), e.g. as in '~ClassName(bool)', or even just '~ClassName()' with a well-known predicate that enables the destructor to ask GC.AmIFinalizing? Then 'Finalize' and 'Dispose' both wire up to this either automatically by the runtime or in a very straightforward manner. Even without this design, a name like SharedCleanup, or something perhaps a bit nicer, would have made more sense. Bit I digress. :) Unfortunately, I think the ship has mostly sailed on this particular problem.

    Regarding the parameter name. Assuming we like Dispose for the method name (ugh), we really ought not to be asking "are we disposing," but rather "are we finalizing?" In retrospect, a better signature might have been: Dispose(bool isFinalizing). This swaps the boolean meaning and thus isn't doable at this point. This leaves changing the name to something that preserves the boolean value. We could do something like isNotFinalizing or isDisposing, but it's not clear that this is much better. Especially considering that we've already shipped a whole slew of types using the disposing param name... Unfortunately, changing a parameter name is also a breaking change.

    So what is the conclusion? Nothing much. While not a perfectly designed pattern, the sheer number of already disposable types makes it difficult to do good on this one... And surely there are worse off designs in the Framework somewhere (API hall of shame)... Brad's been pretty good at point these out, both in his book and this blog... :)

  • Anonymous
    January 31, 2005
    I personally liked hungarian, with its ability to encode a variables scope, and type. I understand with the move away from C/C++ a varaibles type is not as important. Not have any way to specify scope is more of an issue for me. Without any scopy indicator I have to question what the scope of a variable is, field, local, or param, wether I'm writing or reading a class method.

    Thats my two sense. For what its worth, most projects at ms, require us to NOT use any type of scope prefix.

  • Anonymous
    August 21, 2006
    Since I'm getting started in a new team, these are the kind of documents I am digging up these days....

  • Anonymous
    June 12, 2009
    PingBack from http://greenteafatburner.info/story.php?id=1741

  • Anonymous
    June 13, 2009
    PingBack from http://outdoordecoration.info/story.php?id=302