c# - Generic covariance with interfaces - Weird behavioural contradiction between "is" and "=" operators -
i had complete wtf moment when dealing covariant interfaces.
consider following:
class fruit { } class apple : fruit { } interface ibasket<out t> { } class fruitbasket : ibasket<fruit> { } class applebasket : ibasket<apple> { } note:
applebasketdoes not inherit fromfruitbasket.ibasketcovariant.
later on in script, write:
fruitbasket fruitbasket = new fruitbasket(); applebasket applebasket = new applebasket(); log(fruitbasket ibasket<fruit>); log(applebasket ibasket<apple>); ...and you'd expect, output is:
true true however, consider following code:
applebasket applebasket = new applebasket(); log(applebasket ibasket<fruit>); you'd expect output true, right? well, wrong -- @ least compiler anyway:
false that's strange, perhaps it's performing implicit conversion, similar converting int long. int not kind of long, long can assigned value of int implicitly.
however, consider code:
ibasket<fruit> basket = new applebasket(); // implicit conversion? log(basket ibasket<fruit>); this code runs fine - no compiler errors or exceptions - though learned applebasket not kind of ibasket<fruit>. unless there third option, must doing implicit conversion in assignment.
surely basket - declared ibasket<fruit> - must instance of ibasket<fruit>... mean, that's declared as. right?
but no, according is operator, you're wrong again! outputs:
false ...meaning ibasket<fruit> fruit not instance of ibasket<fruit>... huh?
...meaning following property:
ibasket<fruit> fruitbasket { { ... } } can return both isn't null, , isn't instance of ibasket<fruit>.
further, resharper tells me applebasket ibasket<fruit> redundant in applebasket always of provided type, , can safely replaced applebasket != null... resharper got wrong too?
so, what's going on here? version of c# (unity 5.3.1p4 - it's unity's own branch of mono, based off of .net 2.0) being nut?
based on comments, no small surprise covariance isn't being supported...it added in c#4.
what is incredibly surprising is compiling @ if targeting port based off of .net 2.0
Comments
Post a Comment