I cannot reproduce this, which means something else is happening. I suspect that you really wanted to say that he always returns the truth. Here is what I see here:
using System; public interface IBase {} public interface IAdvanced : IBase {} public class Base : IBase {} public class Advanced : IAdvanced {} class Test { public static bool DoSomething<T>(T item) where T: IBase { return DoSomethingSpecific(item); } public static bool DoSomethingSpecific(IBase item) { return true; } public static bool DoSomethingSpecific(IAdvanced item) { return false; } static void Main() { Console.WriteLine(DoSomething(new Base()));
Now you also write:
I know that since IAdvanced is an IBase type (since it is a child of this interface), this can cause confusion between the two overloaded types of the DoSomethingSpecific method. However, as I understand it with my limited knowledge of C #, the IAdvanced method should be chosen here.
Of course, then you should expect false
to return, while I expect true
be returned.
You see that compiling this method determines the resolution of the overload inside DoSomething<T>
. This choice is made once - not once for every other T
Therefore, if you look in the compiled IL for DoSomething<T>
, you will only see a call to DoSomethingSpecific(IBase)
, never DoSomethingSpecific(IAdvanced)
. There is no polymorphism.
As for how you can βfixβ this, you will need to explain in more detail what you really want to achieve. In particular, what would you like if you had this code:
IBase x = new AdvancedImplementation(); DoSomething(x);
Here T
will be IBase
, but the value will refer to the implementation of IAdvanced
. If you want DoSomethingSpecific(IAdvanced)
executed in this case, and if you use C # 4, then you can use dynamic typing:
public static bool DoSomething(IBase item) { dynamic dynamicItem = item;
Note that the method should no longer be general; it will not do any good.
If, on the other hand, you want to decide what to call based on T
, you will need to use something like ivowiblo's solution.
Personally, I will try to avoid both of these decisions - I usually think that such a thing is a design symptom that can be improved in other ways.