Parent VS. Child Classes - Think Like A Compiler

Posted by Ahmed Tarek Hasan on 10/05/2012 01:30:00 PM with No comments
Some developers get confused when they find that the method they are willing to call takes a class as an input parameter which is the parent/child of the class they already have in hand. They don't know what to do or even when they know, they don't know why it failed/succeeded.

I believe that the best way to understand similar topics is to try to think like the compiler. We all know that C# is a strong typed language. This means that the compiler will not allow any code unless it is sure that this code will not cause type mismatch or such things which cause run time errors. So, lets now try to think like a compiler.


Let's assume that:
  • We have class "A"
  • We have class "B" which is child of "A"
  • "A" has a method with the header "public void f1()"
  • Then "B" also has the same method with the header "public void f1()"
  • Also, "B" has another method with the header "public void f2()"

So, now we have 4 cases to study:
  1. Calling a method which takes "A" as an input parameter passing "A" to it
  2. Calling a method which takes "A" as an input parameter passing "B" to it
  3. Calling a method which takes "B" as an input parameter passing "A" to it
  4. Calling a method which takes "B" as an input parameter passing "B" to it
As we can see, both cases 1 and 4 are straight forward and will not cause any problems so we don't really need to study them. But, we need to study the other two cases 2 and 3.


Calling a method which takes "A" as an input parameter passing "B" to it
  • Let's assume we have a method with header "public void Validate(A input)"
  • Inside the method implementation, the compiler expects the developer to write some code which can access the members of "input" which is an instance of class "A", not "B"
  • This means that the compiler will allow the developer to write "input.f1()" but not "input.f2()" because class "A" doesn't have "f2()"
  • So, when you call "Validate" sending it an instance of class "B", the compiler already knows that "B" is a child of "A"
  • This means that the compiler is sure that whatever members of "A" the method "Validate" uses, it will also be available with "B". This acts as a contract which the compiler fully trusts
  • So, the compiler will allow such behavior

Calling a method which takes "B" as an input parameter passing "A" to it
  • Let's assume we have a method with header "public void Validate(B input)"
  • Inside the method implementation, the compiler expects the developer to write some code which can access the members of "input" which is an instance of class "B" which is a child of "A"
  • This means that the compiler will allow the developer to write "input.f1()" and "input.f2()" because class "B" have both of them
  • So, when you call "Validate" sending it an instance of class "A", the compiler already knows that "B" is a child of "A" which means that "B" may have some members which are not found inside "A" and this could cause a problem
  • This means that the compiler is not sure that whatever members of "B" the method "Validate" uses, it will also be available with "A"
  • So, does the compiler need to wait to see if the method "Validate" uses any of the members of "B" which are not found in "A"????? ......... Does the compiler need to check if class "B" has extended members of "A" or they are just duplicate classes?????............ No, the compiler takes a restrictive decision here that the whole thing doesn't depend on the method implementation or the classes relative structure rather than applying a more concrete rule; strong typed rule
  • So, the compiler will not allow such behavior


So, whenever you feel that you don't know if a certain approach can succeed compiler-wise, try to think as a compiler which always wants to make sure that the code will be safe and cause no run time errors.


Hope this approach helps you understand some basic rules.



Categories: ,