2012-06-04 10 views
7

Ich habe die folgenden zwei Funktionen, die fast identisch sind, der einzige Unterschied ist, dass man func verwendet, die andere action. Und ich würde sie gerne in einer Funktion kombinieren, wenn es möglich ist.C# Möglichkeit, Func mit void zurück zu schreiben

private static void TryCatch(Action action) 
    { 
     try 
     { 
      action(); 
     } 
     catch (Exception x) 
     { 
      Emailer.LogError(x); 
      throw; 
     } 
    } 

    private static TResult TryCatch<TResult>(Func<TResult> func) 
    { 
     try 
     { 
      return func(); 
     } 
     catch (Exception x) 
     { 
      Emailer.LogError(x); 
      throw; 
     } 
    } 

Antwort

3

Die Kombination dieser beiden in einer Funktion in C# ist wirklich nicht möglich. Die void in C# und CLR, ist einfach kein Typ und hat daher andere Rücksendsemantik als eine nicht-void-Funktion. Die einzige Möglichkeit, ein solches Muster richtig zu implementieren, besteht darin, eine Überlastung für void- und non-void-Delegierte bereitzustellen

Die CLR-Einschränkung bedeutet nicht, dass es nicht in jeder CLR-Sprache möglich ist. In Sprachen, die void verwenden, ist es unmöglich, eine Funktion darzustellen, die keine Werte zurückgibt. Dieses Muster ist in F # sehr machbar, da es Unit anstelle von void für Methoden verwendet, die einen Wert nicht zurückgeben können.

+0

Vielen Dank für die Erklärung, warum es nicht möglich ist. – CaffGeek

4

Sie könnten Ihre zweite, Func<T> Version verwenden, um die Action Methode zu implementieren, indem Sie einfach die Aktion in ein Lambda wickeln. Dadurch wird ein Teil des duplizierten Codes entfernt.

private static void TryCatch(Action action) 
{ 
    Func<object> fun => 
     { 
      action(); 
      return null; 
     }; 
    TryCatch(fun); 
} 

Davon abgesehen, gibt es zusätzlichen Aufwand dabei daran beteiligt, so persönlich, ich es wahrscheinlich den Weg verlassen würde Sie zur Zeit es umgesetzt haben (vor allem da, wie kurz und einfach Ihre ursprüngliche Version in sein geschieht dieser Fall).

+0

+1 Siehe meine Antwort für eine alternative Syntax. –

+0

Danke, wie vorgeschlagen Ich werde es so lassen wie es ist. Sucks Ich kann es eigentlich nicht in eine einzige Funktion reduzieren. – CaffGeek

+0

@Chad Nein - du könntest es zu einem One-Liner machen - ich teile es in zwei Teile auf, damit du sehen kannst, was passiert, aber deine Methode ist kurz genug, um es zu verlassen. Es gibt jedoch keine Möglichkeit, die Überlastung der Methode zu beseitigen. –

1

Ich mache dies als @ReedCopsey schlägt vor.

Dies ist die einfachste Syntax habe ich gefunden:

private static void TryCatch(Action action) 
{ 
    TryCatch(() => { action(); return 0; }); 
} 
+0

Wie würden Sie das tun, wenn Sie einen Parameter an die Func übergeben müssen? – Nicknow

Verwandte Themen