Syntax
Indent blocks two spaces. Make sure your editor uses spaces only, no tabs.
Use the same bracing style as was used in the Java
code branch. Braces are required around every block, even single-line ones.
Opening braces go at the end of function signatures, ifs,
try/catch statements, etc.
Don't put a space before or after left parentheses,
except for after a language keyword like if or for.
Put one space before left parentheses in that case.
Try to minimize your use of parentheses. You can rely
on operator precedence and associativity to disambiguate most expressions, so
only use parentheses if you need to override the default
precedence/associativity rules. For example, || has lower
precedence than &&, which has lower precedence than
relational operators like == and <=, which in turn
have lower precedence than arithmetic operators. So writing
if (index >= 0 && index < array.Count - 1 || array.isEmpty)
is preferable to
if (((index >= 0) && (index < array.Count - 1)) || (array.isEmpty))
Here's an example demonstrating all of these guidelines:
try {
File file = new
File("sample.txt");
String line = null;
while ((line = file.readLine()) !=
null) {
output.writeLine(line);
}
}
catch (IOException exception) {
}
finally {
}
C# niceties
C# has a few syntactic niceties over Java. Instead of
getXXX and setXXX methods use properties, like
so:
public int Length {
get { return this.length; }
set { this.length = value; }
}
C# also has enumerations, a feature Java inexplicably
left out. For a list of constants, don't create a series of static final
int variables, or whatever. Instead, do this:
public enum XPathTokenType {
/// <summary>Left parenthesis
'('.</summary>
LeftParenthesis,
/// <summary>Right parenthesis
')'.</summary>
RightParenthesis,
/// <summary>Left square bracket
'['.</summary>
LeftBracket,
/// <summary>Right square bracket
']'.</summary>
RightBracket,
/// <summary>Current node
'.'.</summary>
Dot,
/// <summary>Parent node
'..'.</summary>
DotDot,
/// <summary>Attribute sign
'@'.</summary>
AttributeSign,
/// <summary>Comma
','.</summary>
Comma,
/// <summary>Axis separator
'::'.</summary>
ColonColon,
...
}
Naming conventions
C# has a slightly different naming convention from that of Java or C++. In C#, all public members should be capitalized—even functions and variables. Private members are distinguished by having names in lower case.
As a rule, don't abbreviate words in names. Always spell out every word completely, even if the name is long.
Boolean variables/properties/functions should usually
begin with is or something similar, such as isEmpty.
This is a standard naming convention to make code read more like English, and
is an easy way to distinguish booleans from other types.
Otherwise, avoid tagging variables with
prefixes/suffixes indicating their type. For array or list variables, instead
of adding "list" or "array" at the end of the variable
name, make it plural. So elements is better than
elementList.
XML Documentation
Please document every class, method, property, and variable—even private ones! Learn and use the C# XML documentation format. It's basically like Javadoc, except everything's marked up with XML tags. The MSDN Library has full documentation of all the tags. Visual Studio will generate a documentation template when you start an XML comment, automatically adding tags for each parameter to a function, for example.
There are several reasons why this is very important to do:
- If you get into the habit of commenting code as you write it, it's an easy CMMI practice to follow.
- Just like Javadoc, we can dump these comments to HTML pages, getting full API documentation for "free".
- Visual Studio understands these comments. It will popup tooltips when you hover over variables/methods/etc. that have been documented.
- If you tag everything well, the compiler will warn you when comments get out of date, like if you rename a variable but don't update the comment.
It's really important to tag every reference to a
variable/function/class/whatever in your comments. You can do this by adding
the cref attribute to any tag, or by using the
<param/> tag for parameter names.
/// <summary>Validates the
given XML document and returns an <c cref=
/// "XmlDocument">XmlDocument</c>
containing the document.</summary>
///
/// <param name="xmlReader">A reader
referencing the XML document to validate.
/// </param>
/// <param name="grammarNamespace">The
namespace for grammar
elements.</param>
///
/// <returns>An <c
cref="XmlDocument">XmlDocument</c> containing the
document.
/// </returns>
///
/// <exception
cref="XmlSchemaException">Thrown if
the document does not
/// validate against the
schema.</exception>
/// <exception cref="XmlException">Thrown
if the document is
invalid for a
/// reason not expressed in
the schema.</exception>
private XmlDocument loadDocument(XmlReader
xmlReader, string grammarNamespace) {
...
}
Exceptions
Exceptions should be used extensively for error-handling whenever possible. Always use the most specific exception possible. It's a bit cumbersome, but you should always try to create a custom exception class for each type of error. In the long run, the payoff is large.
If we do this properly, then we can observe the most important tenet of exception handling: only catch an exception if you can actually deal with it at that point. The reason exceptions are better than old-style error codes is that you don't have to handle errors immediately. You can let somebody higher up in the call chain handle an error if you don't have any particular recourse.
So instead of catching an exception, logging the stack trace, and moving on, just let the exception propagate upwards. It's a good idea to wrap the exception if you can, but you should rethrow it unless you are able to fix whatever problem caused the exception.
Miscellaneous
Distinguish between externally visible classes and
internal FormFaces ones. Use internal for most classes; use
public only for classes that are to be part of the external
FormFaces API.
(This does not apply to methods; if the class is
already internal, you should just make the methods
public. You'd only need to make a method internal if
it belongs to a public class but should only be called from within
FormFaces.)
Always qualify references to class variables with
this..