Come restituire il valore da Action ()?


92

Per quanto riguarda la risposta a questa domanda Passaggio di DataContext in Action () , come restituisco un valore da action (db)?

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

Dovrebbe essere più simile a:

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

Risposte:


97

Il tuo metodo statico dovrebbe andare da:

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

Per:

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

Questa risposta è nata dai commenti, quindi ho potuto fornire il codice. Per un'elaborazione completa, vedere la risposta di @ sll di seguito.


113

Puoi usare Func<T, TResult>delegato generico. (Vedi MSDN )

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

Inoltre ci sono utili delegati generici che considerano un valore di ritorno:

  • Converter<TInput, TOutput>( MSDN )
  • Predicate<TInput>- restituisce sempre bool ( MSDN )

Metodo:

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

Delegato generico:

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

Eseguire:

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

O esplicitamente:

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

Giusto, puoi fornire un esempio di come dovrebbe essere il metodo?
4th Space

5
@LB - chiedere alle persone di google non è costruttivo. COSÌ esiste per fornire risposte complete.
Kirk Woll

5
@KirkWoll Ma la risposta dà gli ingredienti , non deve essere cotto
LB

9
@LB - è meglio che sia completo. Trovo la tua analogia falsa.
Kirk Woll

1
@LB, meglio non commentare poiché non stai aggiungendo alcun valore come mai.
4th Space

15

Puoi anche trarre vantaggio dal fatto che un metodo lambda o anonimo può chiudersi su variabili nel suo ambito di inclusione.

MyType result;

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

//do something with result

sì, questo si chiama chiusura (materiale di linguaggio funzionale che è disponibile anche per noi)
sll

4

Usa Func<T>invece di Action<T>.

Action<T>agisce come un metodo void con parametro di tipo T, mentre Func<T>funziona come una funzione senza parametri e che restituisce un oggetto di tipo T.

Se desideri fornire parametri alla tua funzione, usa Func<TParameter1, TParameter2, ..., TReturn>.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.