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:
applebasket
does not inherit fromfruitbasket
.ibasket
covariant.
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