Assume I have an interface such as
public interface IInterface<in TIn, out TOut> {
IInterface<TIn, TOut> DoSomething(TIn input);
}
TIn
being contra-variant, and TOut
being co-variant.
Now, I want callers to be able to specify some function to be executed on the input's value, so naïvely I would add the following method to the interface:
IInterface<TIn, TOut> DoSomethingWithFunc(Func<TIn, TOut> func);
which … does not work. TIn
is now required to be covariant, and TOut
contravariant.
I understand, that I cannot use covariant generic types as input for methods, but I thought I could use them in a nested generic type which itself specifies the variance (Func<in T1, out TResult>
).
I tried creating a new delegate type with co-/contravariant types and change the interface to accept an argument of this type, to no avail (same error).
public delegate TOut F<in TDlgIn, out TDlgOut>(TDlgIn input);
public interface IInterface<in TIn, out TOut> {
IInterface<TIn, TOut> DoSomethingWithFunc(F<TIn, TOut> func);
}
I there a way I can make the compiler happy? Is this even possible (for instance with other nested types, or additional generic arguments)? If not, why not?
This would not be safe since you could then use it to do:
public class Id<I, O> : IInterface<I, O>
{
private Func<I, O> f;
public Id(Func<I, O> f) { this.f = f; }
public IInterface<I, O> DoSomething(I i) { this.f(i); return this; }
public IInterface<I, O> DoSomethingWithFunc(Func<I, O> newF) {
this.f = newF;
return this;
}
}
and then
Func<Animal, string> fa;
IInterface<object, string> oi = new Id<object, string>(_ => "");
Interface<Monkey, string> mi = oi; //safe
IInterface<Monkey, string> mi2 = mi.DoSomethingWithFunc(fa);
oi.DoSomething("not an animal!");
at this point you will have passed a string
to an Func<Animal, string>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With