Well, that struck me as a blatant violation of LSP, because now if you use a subclass of a dog, either in production code, unit testing mock, or as a part of dependency injection interceptor this code will not work the same way. I believe this particular scenario can be fixed easily, by changing condition to:

if (animal is Dog)

That got me thinking though:

Are there any other pitfalls to look for that can break LSP in client code?

UPDATE

Just to clarify, I am looking for possible pitfalls in code that uses the class in a hierarchy. I am aware and I am not looking for problems with badly contstructed hierarchies - (e.g. rectangle - square problem). I am trying to find out what to look for, to make sure that the code will support dynamic mocks, interceptors, decorated classes (e.g. LoggingDog) the same way as it would handle original class.

So far after going through the answers and links I can see that the only pitfall would be to use type of the class directly - that is use GetType() method directly or through some other technology. Despite some comments here is and as operators, and even casting to base type will not break LSP in this case, as sub-classes will evaluate the same way the original class would.

I don't see what C++ has to do with anything, you would have the same problem with C++ code (though obviously you'd be using typeof for both as C++ doesn't have an object base type). It may also be that the code actually doesn't want to do something if it's a derived version of dog. This may be intentional.
–
Erik FunkenbuschFeb 3 '13 at 4:16

I mentioned C++, as I figured this was a habit out of RTTI in C++. I am pretty sure in this case it was not intentional, although I see your point.
–
Sebastian KFeb 3 '13 at 4:23

I updated the question, sorry, maybe I was not too clear. I just wanted to know how to identify client code that maybe breaking LSP
–
Sebastian KFeb 3 '13 at 20:08

@Sebastian K: So you are finding all possibility of that, right?
–
Ken KinFeb 3 '13 at 23:27

you are correct. In my case however this code corresponds to a piece of code launching a proper wizard in UI layer based on type of the domain object type. I cannot really change it, and also this code would not belong in Domain object as it is UI logic.
–
Sebastian KFeb 4 '13 at 14:55

Clearly some of it does, as it depends on the domain object. You could simply pass in an IWizardLauncher to the Process method and have the domain object invoke it when it has done its part. All I'm saying is that there are proper solutions that don't break your architecture and still do not require casting.
–
Morten MertnerFeb 4 '13 at 18:25