Alex Burtsev
Alex Burtsev

Reputation: 12668

How can I compact lots of small Try-Catch blocks when handling exceptions in C#?

In my object conversion code I have tons of:

    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);
    }

And so on... I do not want all conversion to fail cause of some property so I can't put all this in one try block, but I need to log if something fails and continue..
Is there a way to compact all this try catch things?

Pity we can't write in C# code like:

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)
}

Upvotes: 8

Views: 3013

Answers (6)

vc 74
vc 74

Reputation: 38179

No but you can:

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

and then

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

Upvotes: 11

Tom
Tom

Reputation: 3374

Whilst I'm not sure about the Exception block shortening, I like the idea you've proposed. It's similar to On Error Resume Next in VB of old. When doing loads of Parse-ing, I'd go down the route of using TryParse when it's available. You could then say something like:

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

Upvotes: 0

SpeksETC
SpeksETC

Reputation: 1013

You could write a SafeConvert class that encapsulates the converting and logging as such:

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;
 }

}

Upvotes: 0

Bob Black
Bob Black

Reputation: 2405

You could use the TryParse methods, when available. See below sample code for parsing an Int32 value.

   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);
      }
   }

Upvotes: 13

JaredPar
JaredPar

Reputation: 754565

It sound like you're looking for something akin to VBs On Error + Resume Next. C# has no such facility. The best way of compacting I can think of is to use lambda expressions and helper methods.

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); });

Upvotes: 1

cdhowie
cdhowie

Reputation: 168988

You could do something like this:

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

Then:

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

Upvotes: 4

Related Questions