Take the 2-minute tour ×

In a project I worked recently, noticed that some methods that were accepting a class that belongs to a hierarchy, had code similar to following:

public void Process(Animal animal) {
    if(animal.GetType() == typeof(Dog)) {
        Console.WriteLine("We have a dog");
    else {
        Console.WriteLine("not a dog");

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?


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.

share|improve this question
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 Funkenbusch Feb 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 K Feb 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 K Feb 3 '13 at 20:08
@Sebastian K: So you are finding all possibility of that, right? –  Ken Kin Feb 3 '13 at 23:27
add comment

1 Answer

If we ignore for the moment that there are indeed cases where you may need to cast to a specific type, in most cases the problem can be solved by changing the design:

public class Animal
    public virtual void Process()
        Console.WriteLine("Animal (not a dog)");

public class Dog : Animal
    public override void Process()
        Console.WriteLine("We have a dog");

By using this design, we avoid the need to cast in the code processing the animals:

var animal = ...; // maybe a Dog, maybe not
share|improve this answer
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 K Feb 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 Mertner Feb 4 '13 at 18:25
add comment

Your Answer


