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.