2010-12-09 48 views
7

Dans mon code de conversion d'objets que j'ai des tonnes de:Comment puis-je compacter beaucoup de petits blocs Try-Catch lors de la gestion des exceptions en C#?

try 
    { 
     NativeObject.Property1= int.Parse(TextObject.Property1); 
    } 
    catch (Exception e) 
    { 
     Trace.WriteLineIf(ConverterSwitch.TraceVerbose, e); 
    } 
    try 
    { 
     NativeObject.Property2= DateTime.Parse(TextObject.Property2); 
    } 
    catch (Exception e) 
    { 
     Trace.WriteLineIf(ConverterSwitch.TraceVerbose, e); 
    } 

Et ainsi de suite ... Je ne veux pas toutes les conversions à l'échec cause de certains biens, donc je ne peux pas mettre tout cela dans un seul bloc d'essai, mais j'ai besoin de se connecter si quelque chose échoue et continue ..
Existe-t-il un moyen de compacter tout cela pour essayer d'attraper des choses?

Dommage que nous ne pouvons pas écrire dans le code C# comme:

try 
{ 
    int num = int.Parse("3"); 
    decimal num2 = decimal.Parse("3.4"); 
} 
catch (Exception e) 
{ 
    Trace.Write(e); 
    continue; //continue execution from the point we left. (line 2) 
} 
+2

Si vous passez à VB.NET, vous pouvez utiliser 'On Error Resume Next' :-) –

+1

Quelque part, un VB6/développeur VBA est ricaner à vous. Je n'ai jamais pensé que j'entendrais quelqu'un pinter pour "Sur l'erreur reprends ensuite" – JohnFx

+2

@Cody: Oh, mon Dieu. Oh, mon Dieu non. Je t'en prie, non. – cdhowie

Répondre

8

Non, mais vous pouvez:

private static void ExecuteAndCatchException(Action action) 
{ 
    try 
    { 
    action(); 
    } 
    catch (Exception e) 
    { 
    Trace.Write(e); 
    } 
} 

puis

ExecuteAndCatchException(() => NativeObject.Property1 = int.Parse(TextObject.Property1)); 
ExecuteAndCatchException(() => NativeObject.Property2 = DateTime.Parse(TextObject.Property2)); 
+1

Il est dommage que cela ne compile pas vraiment à partir de fautes de frappe ...: P – cdhowie

+0

@cdhowie, oups, je n'ai pas essayé de le compiler, où sont les fautes de frappe? –

+0

@vc: 'Action();' - aussi, la méthode devrait être statique car 'this' n'est jamais utilisé. – cdhowie

3

Vous pourriez faire quelque chose comme ça :

private static void Attempt(Action action) 
{ 
    try { action(); } 
    catch (Exception e) { 
     Trace.WriteLineIf(ConverterSwitch.TraceVerbose, e); 
    } 
} 

Puis:

Attempt(() => NativeObject.Property1 = int.Parse(TextObject.Property1)); 
Attempt(() => NativeObject.Property2 = DateTime.Parse(TextObject.Property2)); 
1

sonner comme vous cherchez quelque chose de semblable VBS On Error + Resume Next. C# n'a pas de telle facilité. Le meilleur moyen de compactage auquel je puisse penser est d'utiliser des expressions lambda et des méthodes auxiliaires.

private void Wrap(Action del) { 
    try { 
    del(); 
    } catch (Exception e) { 
    Trace.WriteLineIf(ConverterSwitch.TraceVerbose, e); 
    } 
} 

Wrap(() => { NativeObject.Property1= int.Parse(TextObject.Property1); }); 
Wrap(() => { NativeObject.Property2= DateTime.Parse(TextObject.Property2); }); 
12

Vous pouvez utiliser les méthodes TryParse, lorsqu'elles sont disponibles. Voir ci-dessous un exemple de code pour analyser une valeur Int32.

private static void TryToParse(string value) 
    { 
     int number; 
     bool result = Int32.TryParse(value, out number); 
     if (result) 
     { 
     Console.WriteLine("Converted '{0}' to {1}.", value, number);   
     } 
     else 
     { 
     if (value == null) value = ""; 
     Console.WriteLine("Attempted conversion of '{0}' failed.", value); 
     } 
    } 
+1

Oui, cette approche est la bonne, en supposant que l'exemple de code de la question illustre avec précision l'étendue de ce que vous voulez accomplir avec ces blocs Try-Catch imbriqués. Il est toujours préférable de * prévenir * les exceptions lorsque cela est possible plutôt que d'essayer de les gérer. –

+1

Bonne réponse! +1 pour résoudre le problème réel au lieu de répondre à une question sur la solution de contournement. – JohnFx

+0

+1 TryParse est la meilleure solution si vous souhaitez ignorer les erreurs d'analyse. – juharr

0

Vous pouvez écrire une classe SafeConvert qui encapsule la conversion et l'enregistrement en tant que tel:

public static class SafeConvert{ 

    public static int ParseInt(string val) 
    { 
    int retval = default; 
    try 
    { 
     retval = int.Parse(val); 
    } 
    catch (Exception e) 
    { 
     Trace.WriteLineIf(ConverterSwitch.TraceVerbose, e); 
    } 
     return retval; 
} 

}

0

Alors que je ne suis pas sûr de la réduction du bloc d'exception, j'aime l'idée vous avez proposé. C'est similaire à On Error Resume Next dans VB de l'ancien. Lorsque j'effectue des analyses, j'utilise TryParse quand il est disponible. Vous pouvez alors dire quelque chose comme:

If(!DateTime.TryParse(TextObject.Property2, out NativeObject.Property2)) { 
    // Failed! 
}