The Func
family of delegates (or Action
for that matter) are nothing but simple delegate types declared like
//.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. Delegates as such can have out/ref parameters, so in your case its only a matter of custom implementation by yourself as other answers have pointed out. As to why Microsoft did not pack this by default, think of the sheer number of combinations it would require.
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)
for just two parameters. We have not even touched ref
. It would actually be cumbersome and confusing for developers.
T
as contravariant, andV
as covariant. However, since a parameter (output
) of typeU
is passed by reference,U
cannot be marked co- or contravariant and must remain "invariant". So considerpublic delegate V MyDelegate<in T, U, out V>(T input, out U output);
if you use C# 4 or later. – Turnout