It's just a matter of type inference that doesn't quite work in your favor when combined with overload resolution. It is easy to fix by simply specifying the type argument explicitly - no casting required:
DoTheFoo<Bar>(foo);
I usually get nervous due to overloads that accept quite different types of parameters. Often the code becomes simpler if you just pass methods to other names. Among other things, your readers should not try to perform overload resolution simultaneously with the type of output ...
EDIT: I believe the problem is that ordering works as follows:
- Both methods found
- Type inference applies to both methods without checking constraints - therefore, for the first method, we get
T = Foo<Bar> , and for the second method we get T = Bar . Both methods are currently applicable. - An overload is performed that determines that the first method is the most specific.
- Only after overload resolution has been performed, the restriction on
T noted - and this does not work, because there is no reference to the conversion from Bar to IFoo .
There Eric Lippert on the blog about why the language is designed this way , I wrote about it , and the article I wrote about overload in general . Each of them may or may not help :)
EDIT: Leaving for a while the output of the output method, the reason the first method is more specific is that in one case we go from Foo<Bar> to Foo<Bar> , and in the other from Foo<Bar> to IFoo<Bar> . According to section 7.5.3.3 of the C # 5 specification:
Given the implicit conversion of C1, which is converted from the expression E to type T1 and the implicit conversion of C2, which is converted from the expression E to type T2, C1 is a better conversion than C2 if at least one of the following statements: - E is of type S, and identity transformation exists from S to T1, but not from S to T2 -...
The transformation of identity occurs from type to self, which is the case for the first overload, but not for the second. So, the first conversion is better.
Jon skeet
source share