I enjoy and highly recommend Juval Lowy\'s - C# Coding Standard. Juval explicitly avoids rationale for each directive in order to keep the standard tight (see the preface). Howe
A lot of these guidelines speak to the "quality attributes" of good software design (i.e. maintainability, reliability, reusability, testability, expandability, debugability, interoperability, and what other -ilities you can name).
Often people create code that works fine at the time but may not be the best choice when considering all the quality attributes (in the sense of "where can this software go in the future" or "someone else has to use this code, too").
For example:
2.29 Avoid using the ternary conditional operator
I have no problem with ternary expressions, per se, but by writing code such as: int result = CheckMethod() ? OnTrueDoThis() : OnFalseDoThat()... you are saying, "I have a conditional that, if true (or false), you can do one and only one thing." The whole construct discourages expandability. You have to recreate the construct (with an if..else statement).
Similarly...
2.31 Avoid function calls in Boolean conditional statements. Assign into local variables and check on them.
You called a function and essentially "discarded" the results for later use. If that information is needed later, either the function would have to be called again or the structure of the code would have to be rewritten. It would also make checking or logging the results (for future debugging) more difficult.
Obviously, I'm not Juval, but I can take a stab at these
1.13 Avoid fully qualified type names. Use the "using" statement instead.
Performance can't be the issue here. I'm sure the issue is readability.
1.26 Use empty parenthesis on parameterless-anonymous methods. Omit the parenthesis only if the anonymous method could have been used on any delegate.
public delegate void Foo1();
public delegate void Foo2(int val);
public void Foo()
{
Foo1 first = delegate { Console.WriteLine("Hello world"); };
Foo2 second = delegate { Console.WriteLine("Hello world"); };
Foo1 third = delegate() { Console.WriteLine("Hello world"); };
Foo2 fourth = delegate() { Console.WriteLine("Hello world"); }; // does not compile
}
Without the parens, the anonymous delegate can be applied to any delegate. With the parens, you're being specific about the signature of the delegate. Prefer the second syntax unless you really need the flexibility.
2.19 Avoid defining custom exception classes
Again, readability is the issue here. The framework exception classes are rich and well-understood. Be wary when replacing them.
2.29 Avoid using the ternary conditional operator
It's a readability and expandability thing. I don't really agree, but it's a standard religious fight.
2.31 Avoid function calls in Boolean conditional statements. Assign into local variables and check on them.
Partially this is readability, and partially it's for ease of debugging. I've starting to assign almost everything to temporary variables just so that they're easily found in the debugger later on.
2.47 Avoid interfaces with one member.
"Avoid" is kinda like "prefer", he's just saying think twice before you do it. If you only have one member, is the interface really modeling something useful and complete in your design? It's pretty rare to have a class with just one member, think seriously about why your interface is any different.
2.53 Prefer using explicit interface implementation
This is similar to the idea of using the least-public accessor you can. If your class doesn't need to make the interface public, then it probably shouldn't. This is going to differ significantly based on your design, obviously, but given the fact that most people just make the interface implicit without really thinking about it, it's advice worth considering.
1.26 is about pre-lambda delegate { }
syntax.
// #1 Empty parenthesis on parameterless-anonymous methods would be:
delegate() { }
// #2 ... anonymous method could have been used on any delegate, is:
delegate { }
Remember, the latter can be assigned to any delegate, regardless of its parameters. The delegate just ignores these using some compiler trickery.
If you define a delegate taking no parameters, explicitly say so using #1. Don't "leave the parenthesis out because your delegate doesn't take any parameters anyway".
Here are some of my reactions of which I dare answer them :)
1.13 Avoid fully qualified type names. Use the "using" statement instead.
I disagree. It's certainly not performance related. It can lead to improved readability to have var foo = new Foo()
instead var foo = new MyCompany.MyNamespace.Helpers.Xml.Foo()
but other than that - no.
2.19 Avoid defining custom exception classes This is nonsense imho. You should avoid creating custom exceptions that derive from ApplicationException, but there is nothing wrong with custom exceptions (as long as you're not going to reinvent existing exceptions that is).
2.29 Avoid using the ternary conditional operator I have no idea why that would be a guideline. I have read that not all people use it and may not recognize it, but that is not a valid reason to not use a useful operator.
2.31 Avoid function calls in Boolean conditional statements. Assign into local variables and check on them. This is simply a readability issue in my opinion.
2.47 Avoid interfaces with one member. I also disagree here. You should avoid 'marker' interfaces though - interfaces with no marker, but who just serve the purpose that something is '...ble'. But, one method on an interface seems fine to me.
This is my best stab at the questions you've listed. For the ones that I can't really say, I've omitted.
1.13 Avoid fully qualified type names. Use the "using" statement instead.
Readability. It's must harder to read code when you have to read fully qualified type names.
2.19 Avoid defining custom exception classes
The .NET framework comes with a good set of exceptions built into the system. Unless the exception you're modeling is business domain specific, you'll probably be able to use one of the existing exception classes.
2.29 Avoid using the ternary conditional operator
I think this is most likely because he thinks people may not understand the operator, but I disagree.
2.47 Avoid interfaces with one member.
He might be warning people of building interfaces that are too thin. However, I would actual say the converse, warning people of making interfaces too verbose. If you've ever had to deal with ASP.NET MembershipProvider, you know what I'm talking about.
2.31 Avoid function calls in Boolean conditional statements. Assign into local variables and check on them.
A couple of reasons I can think of here. Readability. It can make conditional statements hard to understand if you are making function calls in them. Also, it's harder to debug if you're not watching.
2.53 Prefer using explicit interface implementation
I believe his reasoning here is to for brevity. However, I don't actually agree with this assessment. I think Jon is correct, implicit interface should be used when you can, and explicit when appropriate.
2.29 Avoid using the ternary conditional operator I have no problems with "simple" uses of the ternary operator but have recommended against using it in a nested fashion:
// This is fine
x := (conditionA) ? true_resultA : false_resultA;
// This would probably be clearer using if-then-elseif
x := (conditionA) ?
((conditionA1) ? true_resultA1 : (condition2) ? true_result2 : false_result2) :
((conditionA2) ? true_resultA2 : false_resultA2);