Other answers provide good solutions to a common problem.
However, your own code can be simplified into a relatively simple solution ...
First, at the beginning of your == statement, you have the following:
// First test if (a as object == null && b as object == null) { return true; }
This means that it’s too hard to work.
If ClauseBE is a reference type, you only need to compare with null - " as object " is redundant; equally, if ClauseBE is a value type, then it can never be null .
Assuming that ClauseBE is a reference type (the most likely case), then you can simplify this: note that we use Object.Equals() to avoid endless recursion and stack ejection.
// First test if (Object.Equals(a, null) && Object.Equals(b, null)) { return true; }
One useful shortcut is using Object.ReferenceEquals() - which handles zeros for you.
So you could write this instead:
// First test if (Object.ReferenceEquals(a, b)) { return true; }
with the bonus that it also handles the case where a and b are the same exact object.
Once you pass the Object.ReferenceEquals() test, you know that a and b are different.
So your next test:
// Second test if ((a as object == null && b as object != null) || (b as object == null && a as object != null)) { return false; }
can be simplified since you know that if a is null, b cannot be null, etc.
// Second test if (Object.Equals(a, null) || Object.Equals(b, null)) { return false; }
If this test fails, you know that a and b different, and that none of them are equal to zero. A good time to call your overridden Equals() .
// Use the implementation of Equals() for the rest return a.Equals(b as object);