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 або новішу версію.