Func
Семья делегатов (или Action
в этом отношении) не что иное , как простые типы делегатов , объявленные как
//.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)
и т. д. Делегаты как таковые могут иметь параметры out / ref, поэтому в вашем случае это только вопрос индивидуальной реализации, как указали другие ответы. Что касается того, почему Microsoft не упаковала это по умолчанию, подумайте о том, какое количество комбинаций ей потребуется.
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)
только для двух параметров. Мы даже не трогали ref
. Это на самом деле было бы громоздким и запутанным для разработчиков.
T
как контравариантный иV
ковариантный. Однако, поскольку параметр (output
) типаU
передается по ссылке , онU
не может быть помечен как со-или контравариантный и должен оставаться «инвариантным». Так что подумайте, используетеpublic delegate V MyDelegate<in T, U, out V>(T input, out U output);
ли вы C # 4 или новее.