A Func
família de delegados (ou, Action
nesse caso) não passa de simples tipos de delegados declarados como
//.NET 4 and above
public delegate TResult Func<out TResult>()
public delegate TResult Func<in T, out TResult>(T obj)
//.NET 3.5
public delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2)
public delegate TResult Func<T1, T2, T3, TResult>(T1 obj1, T2 obj2, T3 obj3)
etc. Os delegados, como tais, podem ter parâmetros out / ref, portanto, no seu caso, é apenas uma questão de implementação personalizada por você, como outras respostas indicaram. Por que a Microsoft não empacotou isso por padrão, pense no grande número de combinações necessárias.
delegate TResult Func<T1, T2, TResult>(T1 obj1, T2 obj2)
delegate TResult Func<T1, T2, TResult>(out T1 obj1, T2 obj2)
delegate TResult Func<T1, T2, TResult>(T1 obj1, out T2 obj2)
delegate TResult Func<T1, T2, TResult>(out T1 obj1, out T2 obj2)
por apenas dois parâmetros. Nós nem nos tocamos ref
. Seria realmente complicado e confuso para os desenvolvedores.
T
como contravariante eV
covariante. No entanto, como um parâmetro (output
) do tipoU
é passado por referência ,U
não pode ser marcado como co- ou contravariante e deve permanecer "invariante". Portanto, considerepublic delegate V MyDelegate<in T, U, out V>(T input, out U output);
se você usa C # 4 ou posterior.