![[media/spring-in-action-cover.png]]My notes on the "Spring in Action" book by Craig Walls and Ryan Breidenbach from Manning Publications Co.
Read more »These are my notes on the book "Clean Code" by Robert C. Martin.

I am in agreement with almost everything that this book says; the following notes are either quotes from the book which I found especially interesting and/or especially well written, or they point out issues that I disagree with, or errata which objectively need correction. If some point from the book is not mentioned below, then I agree with it.
Read more »Before reading any further, please read the disclaimer in the C# Bloopers post.
As it turns out, an explicit interface method implementation in C# must be tied to the base-most interface to which it belongs; it cannot be tied to a descendant interface.
namespace Test14
{
class Test
{
interface A
{
void F();
}
interface B: A
{
}
class C: B
{
void A.F() //OK
{
}
void B.F() //error CS0539: 'B.F' in explicit interface declaration is not a member of interface
{
}
}
}
}
Well, sorry, but... it is.
Before reading any further, please read the disclaimer in the C# Bloopers post.
This is a blooper of the Common Language Runtime (CLR), not of the language itself: Stack<T> and Queue<T> derive from ICollection, but not from ICollection<T>, so they do not support the Remove( T ) method! Why, oh why?
Before reading any further, please read the disclaimer in the C# Bloopers post.
When writing generic methods in C#, it is possible to use the 'where' keyword to specify constraints to the types that the generic parameters can take. Unfortunately, these constraints cannot be used for resolving overloaded methods. Case in point:
namespace Test12
{
class Test
{
public static bool Equals<T>( T a, T b ) where T: class
{
return object.Equals( a, b );
}
public static bool Equals<T>( T a, T b ) where T: struct //error CS0111: Type 'Test' already defines a member called 'Equals' with the same parameter types
{
return a.Equals( b );
}
}
}
Before reading any further, please read the disclaimer in the C# Bloopers post.
When you assign an enum to int, you have to cast it. That's good. When you assign an int to enum, you also have to cast it. That's also good. But if you assign zero to an enum, you don't have to cast it! Go figure.
namespace Test11
{
class Test
{
public enum myenum
{
a, b, c
}
void test_myenum( myenum f, int i )
{
i = (int)myenum.a; //need to cast; that's good.
f = (myenum)5; //need to cast; that's still good.
f = 0; //wtf? no need to cast?
}
}
}