tsunami
log in
email
password
links
newest items
tag list
syntax reference
tag:tsunami
history
Christianity: NT says read OT
Luke's recommended book list
tsunami technology
Predicate
Firefox quicksearches
cmd.exe
tsunami
SQL2005: tables from strings
item name
tags
==Naming For the most part, Microsoft seems to have it right in their Naming Guidelines. =Acronyms While MS indicates that both letters in two-letter acronyms should be capitalized, I disagree. For example, I use `Pk` instead of `PK`. We agree that acronyms of length greater than three should only have the first letter capitalized. Even MS seems conflicted about this (see `DbConnection`, `DbCommand`, etc.). =Abbreviations Only the most well-known abbreviations should be used anywhere. An example is `idx` for `index`, often used in string processing. The Visual Studio IDE supports intellisense, so slightly longer variable names should be easy to deal with. =Names Hungarian notation should be avoided almost everywhere! C# is strictly typed, which means that we almost never have to worry about unexpected and unwanted implicit casts. Of particular note are boolean values: they should be named such that their true-false nature is obvious. `Is` is a good prefix for booleans; simple past [tense] verbs are also good (e.g. Hidden, Expanded). In general, variables used in a very limited scope (e.g. only within 10 lines) should often have extremely short names, perhaps even the would-be Hungarian prefix (but nothing else). For example, a `QueryField` would be `qf`. The larger a variable's scope, the more descriptive the name should be. Indices in for loops should almost always be a loop counter: `i`, `j`, and `k`. Variables in `foreach` statements should be short, whether it be a Hungarian prefix or simple noun. Note that `foreach` statements are preferable to `for` loops when the collection being enumerated does not need to be altered and the index is not required. `Enum`s in C# are always referenced by including both the enumerated type name and the particular value (e.g. `Alignment.Left`); this means that enumerated values need not have any prefix. Without any prefixes it is clear that `Alignment.Left` differs from `Direction.Left`. - `PascalCase` - class names - properties - methods - enumerated type names - enumerated values - public fields (rare) - constants (instead of `CONSTANT_VALUE`) - `camelCase` - method parameters - local variables - `_camelCase` (notice the leading underscore) - private fields - protected fields (rare) - Hungarian prefix + `PascalCase` - controls (this might be debatable) - multiple local variables of different datatypes that represent the same value (rare) =Methods returning Objects Any method returning an object has the option of returning `null`. Sometimes it is helpful for the method to throw an exception instead of returning `null` -- in cases where `null` would indicate an error condition. It is suggested that methods starting with `Get` never return `null`, while methods starting with `Find` should not throw exceptions due to the return value otherwise being `null`. If the method will take a while, it is suggested that it start with `Load` (especially when accessing a database); whether or not these methods should always or never throw exceptions on `null` is debatable. ==Logical Constructs C# allows [curly] braces `{}` to be omittted for constructs containing only one statement: {{ if (expression) DoThis(); else DoThat(); while (this.IsWindy) FlyTheKite(); foreach (Book b in Library) b.Read(); }} This is acceptable as long as both the expression and statement are relatively short. If any need to overflow to the next line, braces should be used. For if-else blocks, either all or no statements should be enclosed in braces (mixing is confusing and error-prone). One exception is throwing of exceptions: {{ throw new ArgumentException(string.Format( "SqlDbType {0} has not been given a maximum storage length.", type)); }} When curly braces are used, they should either be all on one line (rare except for short anonymous delegates) or have their own lines: {{ if (complex || involved && expression) { LotsOfFun(); MoreFun(); } if (list.Exists(delegate(QueryField qf) { return qf.GroupLevel != 0; })) Celebrate(); }} Note the spaces between the curly braces and the code inside above; such spaces should only be used when closing and opening curly braces are on one line. Short property setters and getters are another instance where this might be used. Under no conditions should the code be written like the following: {{ if ( a && b ) foo( bar ); }} ==Nested Control Structures Use short-circuiting, `break`/`continue`, and the occasional repeated test to keep code nesting to a minimum. The more deeply code is nested, the harder it is to read and maintain! For example, {{ if (foo) if (bar) ChopWood(); }} should be written as: {{ if (foo && bar) ChopWood(); }} Another example: {{ foreach (Fish f in this.Ocean) { if (f.Gender == Gender.Male) { // lots of code } } }} should be written as: {{ foreach (Fish f in this.Ocean) { if (f.Gender != Gender.Male) continue; // lots of code } }} In cases of extreme nesting cases, it may be desirable to repeat part of a boolean test instead of nesting one if statement inside another. ==Boolean Operations Anyone who writes `if (b == true)` or `if (b == false)` should be shot. Any C# programmer should be familiar with certain aspects of C# operator precedence: {{ 1. comparison (!= == > < >= <=) 2. & 3. | 4. && 5. || 6. assignment (= *= /= %= += -= <<= >>= &= ^= |=) }} Statements consisting of only logical boolean operators and comparison operators don't need superfluous parentheses to make order of operations clear; in more complicated cases this is acceptable. Note that bit tests should take the form `(val & bit) != 0`. ==Comments Comments should not repeat code. If you find yourself commenting on what the code is doing on a granular scale, you should probably be using better names for variables, functions, and whatnot. Tricky code should be very rare. Most comments should be why something is happening. Noteworthy comments should be preceded by something like `// NOTE:` so that they are easily searchable. These prefixes should match the .NET regular expression below, which can be used to determine the different prefixes used in code. {{ (?-i: ( // | /\* | -- | <!-- | <%-- ) [A-Z_-]+ : ) }} Some common ones: - `// NOTE:` - `// HACK:` (something that should probably change, unless the problem is external) - `// TODO:` - `// CASE:` (case sensitivity considerations) - `// MAGIC:` (magic numbers/strings which should be moved to a constant/variable) - `// SECURITY:` - `// CHANGE:` (something that should change rather soon) - `// SYNC:` (used to note when two different places in code are linked somehow) It is often useful to document what the keys and values of a `Dictionary<TKey, TValue>` represent. An exception is when the key is an integer and the value is a class that wraps records in a database, unless the key is not the pk of the record.
some permissive license goes here
contact