Wie kann ich einen Wert von Action () zurückgeben?


92

Wie kann ich in Bezug auf die Antwort auf diese Frage, die DataContext in Action () übergibt , einen Wert aus action (db) zurückgeben?

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

Sollte eher so sein:

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

Antworten:


97

Ihre statische Methode sollte gehen von:

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

Zu:

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

Diese Antwort entstand aus Kommentaren, damit ich Code bereitstellen konnte. Eine vollständige Ausarbeitung finden Sie in der Antwort von @ sll unten.


113

Sie können einen Func<T, TResult>generischen Delegaten verwenden. (Siehe MSDN )

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

Es gibt auch nützliche generische Delegaten, die einen Rückgabewert berücksichtigen:

  • Converter<TInput, TOutput>( MSDN )
  • Predicate<TInput>- immer bool ( MSDN ) zurückgeben

Methode:

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

Generischer Delegierter:

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

Ausführen:

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

ODER explizit:

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

Richtig - können Sie ein Beispiel dafür geben, wie die Methode aussehen sollte?
4. Raum

5
@LB - Leute zu googeln ist nicht konstruktiv. SO existiert, um vollständige Antworten zu liefern.
Kirk Woll

5
@ KirkWoll Aber die Antwort gibt die Zutaten , es muss nicht gekocht werden
LB

9
@LB - es ist besser, wenn es vollständig ist. Ich finde deine Analogie falsch.
Kirk Woll

1
@LB, besser nicht kommentieren, da Sie überhaupt keinen Wert hinzufügen.
4. Raum

15

Sie können auch die Tatsache nutzen, dass ein Lambda oder eine anonyme Methode Variablen in ihrem umschließenden Bereich schließen kann.

MyType result;

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

//do something with result

Ja, das nennt man Closure (funcitonal language stuff, das auch für uns verfügbar ist)
sll

3

Verwenden Sie Func<T>eher als Action<T>.

Action<T>verhält sich wie eine void-Methode mit Parametern vom Typ T, während sie Func<T>wie eine Funktion ohne Parameter funktioniert und ein Objekt vom Typ T zurückgibt.

Wenn Sie Ihrer Funktion Parameter zuweisen möchten, verwenden Sie Func<TParameter1, TParameter2, ..., TReturn>.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.