You might be able to do what you want by using a bounded existential type, which can be encoded in any language with generics and bounded polymorphism, e.g. C#.
The return type will be something like (in psuedo code)
IAB = exists T. T where T : IA, IB
or in C#:
interface IABIAB<IA, IB>
{
R Apply<R>(IABFunc<R>IABFunc<R, IA, IB> f);
}
interface IABFunc<R>IABFunc<R, IA, IB>
{
R Apply<T>(T t) where T : IA, IB;
}
class DefaultIAB<T>DefaultIAB<T, IA, IB> : IAB<IA, IB> where T : IA, IB
{
readonly T t;
...
public R Apply<R>(IABFunc<R>IABFunc<R, IA, IB> f) {
return f.Apply<T>(t);
}
}
Note: I haven't tested this.
The point is that IAB
has to be able to apply an IABFunc<R>
IABFunc for any return type R
, and an IABFunc<R>IABFunc
has to be able to work on any T
which subtypes both IA
and IB
.
The intent of DefaultIAB<T>DefaultIAB
is just to wrap an existing T
which subtypes IA
and IB
. Note that this is different from your IAB : IA, IB
in that DefaultIAB<T>DefaultIAB
can always be added to an existing T
later on.
References: