Development Practices
- Test-first development is the ideal. Code with good, well thought out tests is far more likely to be accepted than code without tests.
- Refactor mercilessly; however, post in Development Discussion before making large, broad-reaching refactorings.
- Small methods (no more than 15 lines) is the ideal.
- Use guard clauses not nested conditionals.
TDD Standards (Unit Testing and Design)
These standards are ideals, and not necessarily the current state of the code
- No unit-testing of private methods. TDD implies it is unnecessary.
- Don't make methods public just so you can test them (see above).
- Use Constructor Dependency Injection where possible.
- Use Dynamic Mocks for Constructor Dependencies.
- Interface-first design is preferred (i.e. all Constructor Dependencies should be interfaces)
- DefaultXYZ as a name is a smell. What exact type of interface are you implementing?
- Use NUnit 2.5 and RhinoMocks 3.5.
Coding Standards
- Respect the brace style. Curly braces almost always at the start of the line:
public Class Foo { public Foo() { Console.WriteLine("Hello World!"); Console.ReadKey(); } }
- It is acceptable to separate out a branching or looping statement onto two lines, the second line should be appropriately indented.
if (skillPoints < 0) throw new ArgumentException(); - Use C# naming conventions: methods, properties, classes and constants should all be written in PascalCase, while local variables, member variables and parameters should be written in camelCase.
Name Type Convention Types ClassName Constants ConstantName Properties and events PropertyName Instance member fields m_variableName Static member fields s_variableName Method parameters parameterName Local variables variableName
- Namespaces should be C# style. They should start with 'EVEMon.*' where * is the Visual Studio Project Name. Sub-namespaces should map to directories where source files are saved.
- Use suffix notation for controls (f.ex. UsernameLabel, UsernameTextBox)
- Comments are essential:
- XML Comments (used for Intelisense) go above class and method declarations and provide a short summary of the class or method, and provide brief details of the parameters and return values.
/// <summary> /// Convert between a CCP DateTime string and a System.DateTime object /// </summary> /// <param name="ccpTime">CCP DateTime string (YYYY.MM.DD HH.MM.SS)</param> /// <returns>System.DateTime</returns> public DateTime ConvertFromCCPDateTime(string ccpDateTime) { . . . - Code comments should be used to explain non-obvious or obscure code, each line does not require its own comment.
- XML Comments (used for Intelisense) go above class and method declarations and provide a short summary of the class or method, and provide brief details of the parameters and return values.
- One file, one class – unless the inner class is private.
- The ternary operator is fine as long as the conditions are very simple.
- Avoid assignment in conditionals – extract to method instead
- Avoid magic numbers, use a nested enum or an inner class with public const members instead.
- Use String.Format() rather than string concatenation.
- Use the Convert class to convert disparate types (float -> int, double -> int, etc.) save casting for types that are actually of the casting type.
- Use tabs to indent code, not spaces.
- Use spaces after punctuation such as commas and spaces, in accordance with standard written grammar. For example, please include spaces after semi-colons, between equals signs and after keywords
for (int i = 0; i < array.Count; i++)
