Polymorphism has been the interviewer's delight for ages. I have been taking interviews for quite some time. And ever since I started preparing questions on C# Polymorphism, I have been getting surprises. To prepare interview questions, I try writing code, verify it and then twist the code snippet to make it "interview-able".
This blog is to highlight some of the surprises that I have got while preparing the questions.
The motive of this blog is to highlight tricky points to keep in mind while writing overloaded Functions with Generic parameter.
To explain the concept, I'll start with this short code snippet and would like readers to predict the output without scrolling down to answer.
If you know the output and the reasoning behind it, then you may leave the rest of blog as you probably are a better expert than the rest of my audience.
And if you are still reading this line, it means you are searching for the answer. You will definitely get to know the answer, but before I reveal it, I would like you to guess the output of the below code:
If you could get the output of the above snippet, then you are one of my category who too will be surprised to see the output of my first problem statement.
And if you couldn't guess the below shown output, it means you need to develop deeper understanding of C# Type conversion and probably this post is of better help than mine:
So finally if you are the filtered one, who is eager to know the answer, then please get yourself ready to get surprised by the answer below:
- Generic is called for
2 instead of short
- String is called for "
s" instead of generic
The question that comes to mind is:
2 was considered as Short in our second code, why was it considered as generic in the first code?
string was not considered as Generic?
The answer to both these questions is the same. It's the way the C# compiler resolves the ambiguity. The compiler always considers any literal digits as integers (
Int32 to be specific) while calling a function until and unless the digit is type casted to other compatible type.
The other point to note is, the compiler tries to do an implicit conversion before doing any boxing unboxing. This is the reason,
2 was downcasted to
short and was not boxed to object in our second example.
So the order of precedence is:
- Exact type match (This is the reason why
string argument was called with
string function and not generic)
- Generic Match (This is why
2 was called with Generic and not
short in our first example)
- Implicit conversion match (This is why
2 was called with
short in our second example)
- Boxed conversion match (Note that there is no provision of implicit unbox match, so you cannot call an
integer function with boxed
Another interesting observation is, in the second code, the short version is called for
32767. As soon as we provide any integer outside this range (say
32768), object version gets called. Obviously, this is in line with our order of precedence as no implicit conversion exists to convert
Hope this was useful. Please feel free to leave relevant feedback.