class Base
, and class Ext extends Base
.
class B<T>
with typed method foo<T>(value:T)
Why B<Base>.foo
doest not accept instance of B<Ext>
(implicit downcast of the type parameter?) by default?
Here is an example http://try.haxe.org/#d443f
class Test {
static function main() {
var bExt = new B(new Ext());
var bBase = new B(new Base());
bBase.foo(bExt);
//ofc
//bBase.foo(cast bExt);
}
}
class B<T>
{
public function new(v:T)
{
}
public function foo(v:B<T>)
{
//
}
}
class Base {
public function new(){}
}
class Ext extends Base {
public function new(){
super();
}
}
Is there any way to trigger implicit cast of the type parameter for B.foo?
There are three ways to interpret and answer your question:
foo(v:B<T>)
:This is your example and it doesn't compile because T
isn't allowed to be be variant. It happens because of the very existence of foo
and because allowing bBase.foo(bExt)
, that is, unifying bExt
with bBase
, will then allow bBaseOfbExt.foo(bBase)
.
It is the fact that foo
exists and that it can potentially modify the type that makes the bExt
unification with bBase
unsafe; you can see a similar (but maybe clearer) explanation in the manual, using arrays: type system – variance.
foo(v:T)
:This is closer to what's on the body of your question (but not in the example) and it works fine.
foo<A>(v:B<A>)
:Finally, if you have a type parameterized method, it also works, but you'd probably face other variance issues elsewhere.