Re: Type inference in extension methods...
Mark Nicholls <[email protected]>
| Newsgroups | gmane.comp.windows.devel.dotnet.advanced |
|---|---|
| Message-ID | <LISTSERV%[email protected]> |
I've simplified it as much as I can! and created and example....Boom9 does work...Boom10 wont infer...even though there is a solution (explicitly stated)...and there's not another obvious one
The difference between the two methods is that Boom10 has a type parameter BarB which is constrained by the explicit constrait
"BarB : ABar<BarB, DNT>"
and should be derivable from the constraint on CompundBarBC
"CompundBarBC : ACompoundBar<CompundBarBC, BarB, DNBar, CompoundFooBC, DNT, DNT>"
in Boom9 BarB doesn't appear and CompundBarBC is explicitly constrained
"CompoundBarBC : ACompoundBar<CompoundBarBC, DNBar, DNBar, CompoundFooBC, DNT, DNT>"
so it would seem in Bar9 the inference works uniquely (assuming that inference implies uniquenes, which I think it does)...and that CompoundBC is derived (in the failed inference on Boom10) to be
"CompoundBar<DNBar, DNBar, CompoundFoo<DNT, DNT>, DNT, DNT>"
naively I would assume that in Boom10 it can derive the same fact as Boom9...yet it does not derive that BarB is DNBar....which I think it has to be....i.e. A : B<C> and A : B<D> means that C == D (as dot net does not support co/contravariance)
P.S. I deliberately use abstract classes rather than interfaces as abstract classes are more constrained (i.e. single inheritance) making the inference as strong as possible.
heres the simplified code!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class Test
{
public static void X()
{
CompoundBar2<DNBar, DNT> y = new CompoundBar2<DNBar, DNT>();
new DNBar().Boom9(y); // inference works
new DNBar().Boom10(y); // inference doesn't work
new DNBar().Boom10< // there is a solution
CompoundBar2<DNBar, DNT>,
CompoundBar<DNBar, DNBar, CompoundFoo<DNT, DNT>, DNT, DNT>,
CompoundFoo<DNT, CompoundFoo<DNT, DNT>>,
CompoundFoo<DNT, DNT>,
DNBar>(y);
}
}
abstract class AFoo<This>
where This : AFoo<This>, new()
{
}
abstract class AFoo2<This> : AFoo<This>
where This : AFoo2<This>, new()
{
}
abstract class ACompoundFoo<This, A, B> : AFoo<This>
where This : ACompoundFoo<This, A, B>, new()
where A : AFoo<A>, new()
where B : AFoo<B>, new()
{
}
class CompoundFoo<A, B> : ACompoundFoo<CompoundFoo<A, B>, A, B>
where A : AFoo<A>, new()
where B : AFoo<B>, new()
{
}
sealed class Foo : AFoo2<Foo>
{
}
sealed class DNT : AFoo2<DNT>
{
}
abstract class ABar<This, A>
where This : ABar<This, A>
where A : AFoo<A>, new()
{
public void
Boom10<CompoundBarABC, CompundBarBC, CompoundFooABC, CompoundFooBC, BarB>(
ACompoundBar<CompoundBarABC, This, CompundBarBC, CompoundFooABC, A, CompoundFooBC> abc)
where CompoundBarABC : ACompoundBar<CompoundBarABC, This, CompundBarBC, CompoundFooABC, A, CompoundFooBC>
where CompundBarBC : ACompoundBar<CompundBarBC, BarB, DNBar, CompoundFooBC, DNT, DNT>
where BarB : ABar<BarB, DNT>
where CompoundFooABC : ACompoundFoo<CompoundFooABC, A, CompoundFooBC>, new()
where CompoundFooBC : ACompoundFoo<CompoundFooBC, DNT, DNT>, new()
{
}
public void
Boom9<CompoundBarABC, CompoundBarBC, CompoundFooABC, CompoundFooBC>(
ACompoundBar<CompoundBarABC, This, CompoundBarBC, CompoundFooABC, A, CompoundFooBC> abc)
where CompoundBarABC : ACompoundBar<CompoundBarABC, This, CompoundBarBC, CompoundFooABC, A, CompoundFooBC>
where CompoundBarBC : ACompoundBar<CompoundBarBC, DNBar, DNBar, CompoundFooBC, DNT, DNT>
where CompoundFooABC : ACompoundFoo<CompoundFooABC, A, CompoundFooBC>, new()
where CompoundFooBC : ACompoundFoo<CompoundFooBC, DNT, DNT>, new()
{
}
}
abstract class ACompoundBar<This, ThisA, ThisB, AB, A, B> : ABar<This, AB>
where This : ACompoundBar<This, ThisA, ThisB, AB, A, B>
where ThisA : ABar<ThisA, A>
where ThisB : ABar<ThisB, B>
where AB : ACompoundFoo<AB, A, B>, new()
where A : AFoo<A>, new()
where B : AFoo<B>, new()
{
}
class CompoundBar<ThisA, ThisB, AB, A, B> : ACompoundBar<CompoundBar<ThisA, ThisB, AB, A, B>, ThisA, ThisB, AB, A, B>
where ThisA : ABar<ThisA, A>
where ThisB : ABar<ThisB, B>
where AB : ACompoundFoo<AB, A, B>, new()
where A : AFoo<A>, new()
where B : AFoo<B>, new()
{
}
class DNBar : ABar<DNBar, DNT>
{
}
class CompoundBar2<BarA, T> :
ACompoundBar<
CompoundBar2<BarA, T>,
BarA,
CompoundBar<BarA, BarA, CompoundFoo<T, T>, T, T>,
CompoundFoo<T, CompoundFoo<T, T>>,
T,
CompoundFoo<T, T>>
where BarA : ABar<BarA, T>
where T : AFoo<T>, new()
{
}
===================================
View archives and manage your subscription(s) at http://peach.ease.lsoft.com/archives