Func <T> с параметром out

Могу ли я передать метод с параметром out в качестве Func?

public IList<Foo> FindForBar(string bar, out int count) { }

// somewhere else
public IList<T> Find(Func<string, int, List<T>> listFunction) { }

Func нуждается в типе, поэтому он не будет компилироваться, а вызов listFunction требует int и не позволит выйти.

Есть ли способ сделать это?

Ответ 1

ref и out не являются частью определения параметра типа, поэтому вы не можете использовать встроенный делегат Func для передачи аргументов ref и out. Конечно, вы можете объявить свой собственный делегат, если хотите:

delegate V MyDelegate<T,U,V>(T input, out U output);

Ответ 2

Почему бы не создать класс для инкапсуляции результатов?

public class Result
{
     public IList<Foo> List { get; set; }
     public Int32 Count { get; set; }
}

Ответ 3

Семейство делегатов 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)

и т.д.. Делегаты как таковые могут иметь параметры /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. Это на самом деле было бы громоздким и запутанным для разработчиков.

Ответ 4

Вы можете обернуть его в метод лямбда/делегат/функция/, который разоблачил правый интерфейс и называется FindForBar, но я подозреваю, что FindForBar подсчитал как параметр out как причину, поэтому вам нужно быть уверенным, что вы выбрали этот информация была в порядке/безопасна/желательна/имела правильные результаты (вам нужно быть уверенным в этом, даже если бы вы могли прямо пройти через FindForBar).