Contributing to AgateLib

If you wish to contribute to AgateLib, there are a few guidelines to follow in formatting and naming conventions for your code. Above all, you should follow the AgateLib coding philosophy: Common use cases should be as easy as possible.

Exceptions

  • Do always include a descriptive message in the exception. Do not write code like this: throw new AgateException();. Detailed messages should include things like the name of the argument that was null or out of range, the invalid value of a variable, or the name of the file that was not found. This is almost always far more important for debugging than the actual exception type. An informative message is more important than choosing the right exception type.
  • Do look at standard .NET exceptions first like ArgumentNullException, IndexOutOfRangeException, or FileNotFoundException when choosing an exception type to throw. If none of these seem appropriate, then throw AgateException. Never throw the following exceptions manually: NullReferenceException, InvalidCastException.
  • Do use descriptive messages even when throwing exceptions like ArgumentNullException or FileNotFoundException.
  • Don't write code that can throw NullReferenceException. ArgumentNullException is much more appropriate if an argument is passed as null.

Public / Protected API Conventions

  • Do follow standard .NET naming conventions for public members, ie. CamelCase for public properties.
  • Don't use out or ref parameters in public methods.
  • Don't create public static methods to construct objects; instead use constructors wherever possible. The exception to this is if multiple constructors are needed with different behaviors but possibly similar types. The Create* static methods of the DisplayWindow class are an example of this exception.
  • Avoid abstract classes meant for consumer code, except for code meant to be implemented by drivers.
  • Avoid virtual methods with non-trivial base class implementations. Virtual members should either do nothing, call a single function or perform a very simple operation. They should never access private members. For a public virtual method is it much better to replace it with a public non-virtual method that calls a protected virtual method.

Code Formatting

  • Do indent with tabs.
  • Do prefix member variables with a lowercase "m" and start the first word with a capital letter, as in "mVariableName".
  • Do prefix static variables with a lowercase "s" instead of "m".
  • Avoid nesting braces where possible, as in this example:
    1. foreach (SomeType variable in someList)
    2. {
    3.     if (variable.Name == somethingImSearchingFor)
    4.     {
    5.         return variable;
    6.     }
    7. }

    This reads better as:
    1. foreach (SomeType variable in someList)
    2. {
    3.     if (variable.Name != somethingImSearchingFor)
    4.         continue;
    5.    
    6.     return variable;
    7. }

    The exception to this rule is using blocks. Use a using block wherever an IDisposable object needs to be destroyed when a method exits.