Agile Zone is brought to you in partnership with:

Sasha Goldshtein is a Senior Consultant for Sela Group, an Israeli company specializing in training, consulting and outsourcing to local and international customers.Sasha's work is divided across these three primary disciplines. He consults for clients on architecture, development, debugging and performance issues; he actively develops code using the latest bits of technology from Microsoft; and he conducts training classes on a variety of topics, from Windows Internals to .NET Performance. You can read more about Sasha's work and his latest ventures at his blog: Sasha writes from Herzliya, Israel. Sasha is a DZone MVB and is not an employee of DZone and has posted 204 posts at DZone. You can read more from them at their website. View Full User Profile

All-In-One Code Framework Coding Standards

  • submit to reddit

I recently stumbled upon the All-In-One Code Framework project on CodePlex. It’s a very impressive collection of samples in C#, VB.NET, and C++, and most of the samples I’ve seen are of superb quality.

One thing that’s cool about this project is that they publish their own set of coding standards. It’s a very elaborate 87-page document written in the “Framework Design Guidelines style” with “DO” and “DO NOT” items sprinkled liberally throughout the guidelines. It’s relevant for C# and C++ developers alike.

Anyway, here are some nuggets of wisdom I gathered from the document:

  • You should use braces around single line conditionals. Doing this makes it easier to add code to these conditionals in the future and avoids ambiguities should the tabbing of the file become disturbed. [Italics mine. –Sasha]
  • Do not use Enum.IsDefined for enum range checks in .NET. There are really two problems with Enum.IsDefined. First it loads reflection and a bunch of cold type metadata, making it a surprisingly expensive call. Second, there is a versioning issue here. [Instead, use > and < to test for the enum value falling within the desired range. –Sasha]
  • Do use ARRAYSIZE() as the preferred way to get the size of an array. ARRAYSIZE() is declared in a way that produces an error if it is used on a non-array type, resulting in error C2784. For anonymous types you need to use the less safe _ARRAYSIZE() macro. ARRAYSIZE() should be used instead of RTL_NUMBER_OF(), _countof(), NUMBER_OF(), etc.
  • Do use "= {}" to zero array memory. The compiler optimizer does better with "= {}" than "= {0}" and ZeroMemory, so "= {}" is preferred.
  • Do not overload operator&&, operator|| or operator,. Unlike the built-in &&, || or , operators the overloaded versions cannot be short-circuited, so the resulting behavior of using these operators typically isn’t what was expected. [This paragraph relates to the C++ version of these operators. –Sasha]
  • Do use IFACEMTHODIMP and IFACEMTHODIMP_ for method declarations in COM interfaces. These macros have replaced the usage of STDMETHODIMP and STDMETHOD as they add the __override SAL annotation.
  • Do declare private destructors (or protected if you expect people to derive from you) for classes that implement COM objects that are allocated on the heap. This avoids clients mistakenly calling “delete pObj”, something that should only happen when the ref count of the object goes to zero.
  • Do implement IEquatable<T> on value types. The Object.Equals method on value types causes boxing and its default implementation is not very efficient, as it uses reflection. IEquatable<T>.Equals can have much better performance and can be implemented such that it will not cause boxing.
  • Do not provide set-only properties. If the property getter cannot be provided, use a method to implement the functionality instead. The method name should begin with Set followed by what would have been the property name.
  • Do use member overloading rather than defining members with default arguments. Default arguments are not CLS-compliant and cannot be used from some languages. There is also a versioning issue in members with default arguments. Imagine version 1 of a method that sets an optional parameter to 123. When compiling code that calls this method without specifying the optional parameter, the compiler will embed the default value (123) into the code at the call site. Now, if version 2 of the method changes the optional parameter to 863, then, if the calling code is not recompiled, it will call version 2 of the method passing in 123 (version 1’s default, not version 2’s default).
  • An internal constructor can be used to limit concrete implementations of the abstract class to the assembly defining the class.
Published at DZone with permission of Sasha Goldshtein, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)