web-dev-qa-db-ja.com

出力パラメータ付きのFunc <T>

Outパラメータを持つメソッドをFuncとして渡すことはできますか?

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

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

Funcは型を必要とするため、outはそこでコンパイルされません。また、listFunctionを呼び出すにはintが必要で、out inを許可しません。

これを行う方法はありますか?

152
blu

refoutは型パラメーター定義の一部ではないため、組み込みのFuncデリゲートを使用してrefout引数。もちろん、必要に応じて独自のデリゲートを宣言できます。

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

結果をカプセル化するクラスを作成してみませんか?

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

デリゲートの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)

たった2つのパラメーターに対して。 refにも触れていません。実際には、開発者にとって面倒で混乱を招くでしょう。

13
nawfal

正しいインターフェイスを公開し、FindForBarを呼び出したラムダ/デリゲート/関数/メソッドでラップすることもできますが、FindForBarは理由としてoutパラメーターとしてカウントしていると思われるため、その情報は必ず破棄する必要があります。 ok/safe/desirable /正しい結果が得られました(FindForBarに直接渡すことができる場合でも、これを確認する必要があります)。

0
Logan Capaldo