Comment retourner la valeur d'Action ()?


92

En ce qui concerne la réponse à cette question Passing DataContext into Action () , comment puis-je renvoyer une valeur de l'action (db)?

SimpleUsing.DoUsing(db => { 
// do whatever with db 
}); 

Devrait être plus comme:

MyType myType = SimpleUsing.DoUsing<MyType>(db => { 
// do whatever with db.  query buit using db returns MyType.
}); 

Réponses:


97

Votre méthode statique doit aller de:

public static class SimpleUsing
{
    public static void DoUsing(Action<MyDataContext> action)
    {
        using (MyDataContext db = new MyDataContext())
           action(db);
    }
}

À:

public static class SimpleUsing
{
    public static TResult DoUsing<TResult>(Func<MyDataContext, TResult> action)
    {
        using (MyDataContext db = new MyDataContext())
           return action(db);
    }
}

Cette réponse est née des commentaires afin que je puisse fournir du code. Pour une élaboration complète, veuillez consulter la réponse de @ sll ci-dessous.


113

Vous pouvez utiliser Func<T, TResult>un délégué générique. (Voir MSDN )

Func<MyType, ReturnType> func = (db) => { return new MyType(); }

Il existe également des délégués génériques utiles qui prennent en compte une valeur de retour:

  • Converter<TInput, TOutput>( MSDN )
  • Predicate<TInput>- renvoie toujours booléen ( MSDN )

Méthode:

public MyType SimpleUsing.DoUsing<MyType>(Func<TInput, MyType> myTypeFactory)

Délégué générique:

Func<InputArgumentType, MyType> createInstance = db => return new MyType();

Exécuter:

MyType myTypeInstance = SimpleUsing.DoUsing(
                            createInstance(new InputArgumentType()));

OU explicitement:

MyType myTypeInstance = SimpleUsing.DoUsing(db => return new MyType());

Droite - pouvez-vous donner un exemple de ce à quoi devrait ressembler la méthode?
— 4thSpace

5
@LB - demander aux gens de google n'est pas constructif. SO existe pour fournir des réponses complètes.
— Kirk Woll

5
@KirkWoll Mais la réponse donne les ingrédients , il n'a pas été cuit
— LB

9
@LB - il vaut mieux que ce soit complet. Je trouve votre analogie fausse.
— Kirk Woll

1
@LB, mieux vaut ne pas commenter car vous n'ajoutez aucune valeur.
— 4thSpace

15

Vous pouvez également profiter du fait qu'une méthode lambda ou anonyme peut fermer des variables dans sa portée englobante.

MyType result;

SimpleUsing.DoUsing(db => 
{
  result = db.SomeQuery(); //whatever returns the MyType result
}); 

//do something with result

ouais, cela s'appelle Closure (langage fonctionnel qui est également disponible pour nous)
— sll

4

Utilisez Func<T>plutôt que Action<T>.

Action<T> agit comme une méthode void avec un paramètre de type T, tandis que Func<T> fonctionne comme une fonction sans paramètres et qui renvoie un objet de type T.

Si vous souhaitez donner des paramètres à votre fonction, utilisez Func<TParameter1, TParameter2, ..., TReturn>.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.