Как я могу сжать много маленьких блоков Try-Catch при обработке исключений в C #? - PullRequest
7 голосов
/ 09 декабря 2010

В моем коде преобразования объекта у меня есть тонны:

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

И так далее ... Я не хочу, чтобы все преобразования заканчивались ошибкой из-за какого-либо свойства, поэтому я не могу поместить все это в однопопробуйте заблокировать, но мне нужно войти, если что-то не получится, и продолжить ..
Есть ли способ сжать все это, попытаться поймать вещи?

Жаль, что мы не можем писать на C #код как:

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

Ответы [ 6 ]

12 голосов
/ 09 декабря 2010

Вы можете использовать методы TryParse, если они доступны. Ниже приведен пример кода для анализа значения 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);
      }
   }
9 голосов
/ 09 декабря 2010

Нет, но вы можете:

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

, а затем

ExecuteAndCatchException(() => NativeObject.Property1 = int.Parse(TextObject.Property1)); 
ExecuteAndCatchException(() => NativeObject.Property2 = DateTime.Parse(TextObject.Property2));
3 голосов
/ 09 декабря 2010

Вы можете сделать что-то вроде этого:

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

Тогда:

Attempt(() => NativeObject.Property1 = int.Parse(TextObject.Property1));
Attempt(() => NativeObject.Property2 = DateTime.Parse(TextObject.Property2));
1 голос
/ 09 декабря 2010

Звучит так, будто вы ищете что-то похожее на VB On Error + Resume Next. C # не имеет такой возможности. Лучший способ сжатия, который я могу придумать, - это использовать лямбда-выражения и вспомогательные методы.

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); });
0 голосов
/ 09 декабря 2010

Хотя я не уверен в сокращении блока исключений, мне нравится идея, которую вы предложили. Это похоже на On Error Resume Next в старом VB. При выполнении множества разборов я бы пошел по пути использования TryParse, когда он будет доступен. Вы могли бы тогда сказать что-то вроде:

If(!DateTime.TryParse(TextObject.Property2, out NativeObject.Property2)) {
    // Failed!
}
0 голосов
/ 09 декабря 2010

Вы можете написать класс SafeConvert, который инкапсулирует преобразование и ведение журнала следующим образом:

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

}

...