Предположим, что у меня есть интерфейс, такой как
public interface IInterface<in TIn, out TOut> {
IInterface<TIn, TOut> DoSomething(TIn input);
}
TIn
является контравариантным, а TOut
является ковариантным.
Теперь я хочу, чтобы вызывающие абоненты могли указать какую-либо функцию, которая будет выполняться на входном значении, поэтому наивно я добавлю следующий метод в интерфейс:
IInterface<TIn, TOut> DoSomethingWithFunc(Func<TIn, TOut> func);
который... не работает. TIn
теперь необходимо ковариантно, а TOut
контравариантно.
Я понимаю, что я не могу использовать ковариантные общие типы в качестве ввода для методов, но я думал, что могу использовать их во вложенном родовом типе, который сам определяет дисперсию (Func<in T1, out TResult>
).
Я попробовал создать новый тип делегата с ко-контравариантными типами и изменить интерфейс, чтобы принять аргумент этого типа, безрезультатно (такая же ошибка).
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);
}
Я могу сделать компилятор счастливым? Возможно ли это (например, с другими вложенными типами или дополнительными генерическими аргументами)? Если нет, почему бы и нет?