web-dev-qa-db-fra.com

Func <T> avec paramètre out

Puis-je passer une méthode avec un paramètre out en tant que Func?

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

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

Func a besoin d'un type pour que out ne soit pas compilé là-bas, et appeler listFunction nécessite un int et n'autorise pas d'entrée.

Y a-t-il un moyen de faire cela?

152
blu

ref et out ne font pas partie de la définition du paramètre type, vous ne pouvez donc pas utiliser le délégué intégré Func pour passer ref et out arguments. Bien sûr, vous pouvez déclarer votre propre délégué si vous voulez:

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

Pourquoi ne pas créer une classe pour encapsuler les résultats?

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

La famille de délégués Func (ou Action d'ailleurs) n'est rien d'autre que de simples types de délégués déclarés comme

//.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. Les délégués en tant que tels peuvent avoir des paramètres out/ref. Dans votre cas, il ne s'agit donc que d'une implémentation personnalisée par vous-même, comme d'autres réponses l'ont souligné. Pourquoi Microsoft ne l’a-t-il pas emballé par défaut, songez au nombre de combinaisons nécessaires.

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)

pour seulement deux paramètres. Nous n'avons même pas touché ref. Ce serait en fait lourd et déroutant pour les développeurs.

13
nawfal

Vous pouvez l'envelopper dans un lambda/délégué/fonction/méthode qui a exposé la bonne interface et appelé FindForBar, mais je suppose que FindForBar a une valeur en tant que paramètre de sortie, vous devez donc être sûr de jeter ces informations ok/safe/souhaitable/a eu les bons résultats (vous devez en être sûr même si vous pouviez simplement passer directement à FindForBar).

0
Logan Capaldo