2013-06-26 33 views
4

所以,我有以下的方法內代碼塊:(所有變量本地)幹着不同的try語句和相同的catch語句

// ... 

try 
{ 
    if (postXml != null) 
     using (StreamWriter writer = new StreamWriter(req.GetRequestStream())) 
      writer.Write(postXml.ToString()); 
} 
catch (WebException ex) 
{ 
    HttpWebResponse response = ex.Response as HttpWebResponse; 
    if (response != null) 
     result = HandleOtherResponse(response, out status); 
    else result = HandleBadResponse(ex.ToString(), out status); 
} 
catch (Exception ex) 
{ 
    result = HandleBadResponse(ex.ToString(), out status); 
} 

if (result == null) 
{ 
    try 
    { 
     HttpWebResponse response = req.GetResponse() as HttpWebResponse; 
     result = HandleOtherResponse(response, out status); 
    } 
    catch (WebException ex) 
    { 
     HttpWebResponse response = ex.Response as HttpWebResponse; 
     if (response != null) 
      result = HandleOtherResponse(response, out status); 
     else result = HandleBadResponse(ex.ToString(), out status); 
    } 
    catch (Exception ex) 
    { 
     result = HandleBadResponse(ex.ToString(), out status); 
    } 
} 

// ... 

正如你可以看到,這兩個try語句是不同的,但這兩組捕捉聲明完全相同。我一直在想辦法讓自己不要在這裏重複自己,但我並沒有真正想到一種不會顯着慢或看起來很糟糕的方式。想知道如果有人有任何想法。

+0

將異常傳遞給相同的函數。 –

回答

4

一種方式是寫一個「安全」的調用方法,並傳遞一個FUNC它:

public T SafeInvocation(Func<T> myMethod) 
{ 
    T result = default(T); 

    try 
    { 
     // Invoke method 
     result = myMethod(); 
    } 
    catch 
    { 
     // Do your common catch here 
    } 

    return result; 
} 

建設行動<牛逼>額外的過載,這樣你就不需要有回報類型。然後,你可以在其他地方調用它,傳遞方法,以你的方法作爲參數(盜):

SafeInvocation(() => 
{ 
    if (postXml != null) 
     using (StreamWriter writer = new StreamWriter(req.GetRequestStream())) 
      writer.Write(postXml.ToString()); 
} 
+1

謝謝,這個想法對我來說非常合適。 – Maltor

0

你可以傳遞一個Action到處理該異常的函數:

private void HandleErrorsFor(Action action) 
{ 
    try 
    { 
     action(); 
    } 
    catch (Exception ex) 
    { 
     //repeated exception handling... 
    { 
} 

//... 

public void DoSomething() 
{ 
    HandleErrorsFor(() => { 
     //try block #1 
    }); 

    HandleErrorsFor(() => { 
     //try block #2 
    }); 
} 

這是一個有點易於閱讀,避免了重複的代碼。

0

你可以做代表什麼,涵蓋trycatch塊:

static class Program 
    { 
     delegate void CodeBlock(); 

     internal delegate void ExceptionCatcher(Exception ex); 


    private static void Main() 
    { 
     CodeBlock b =() => { Console.WriteLine("HELLO WORLD"); }; 
     CodeBlock error =() => { throw new Exception("Exception thrown"); }; 
     ExceptionCatcher silence = exception => { }; 
     ExceptionCatcher e = exception => 
      { 
       var currentColor = Console.BackgroundColor; 
       Console.BackgroundColor = ConsoleColor.Red; 
       Console.WriteLine(exception.Message); 
       Console.BackgroundColor = currentColor; 
      }; 

     DRYRunner(b, e); 
     DRYRunner(error , e); 
     DRYRunner(error , silence); 

     Console.ReadLine(); 
    } 

    static void DRYRunner (CodeBlock block, ExceptionCatcher catcher) 
    { 
     try 
     { 
      block.Invoke(); 
     } 
     catch (Exception ex) 
     { 
      catcher(ex); 
     } 
    } 
} 

編輯:擴展爲此,我們可以創建一個類來幫助包含代碼塊並將其與可能的異常和處理程序關聯起來。您甚至可以創建一類常見異常處理程序並相應地引用它們,並將它們與特定處理程序混合:

class ExceptionHandledDelegate 
{ 
    public delegate void CodeBlock(); 

    public delegate void ExceptionCatcher(Exception ex); 

    public Dictionary<Type, ExceptionCatcher> ExceptionHandlers; 

    public CodeBlock codeBlock { get; set; } 

    public void Run() 
    { 
     try 
     { 
      codeBlock.Invoke(); 
     } 
     catch (Exception ex) 
     { 
      var mn = ex.GetType(); 
      if (ExceptionHandlers.Keys.Contains(mn)) 
      { 
       ExceptionHandlers[mn](ex); 
      } 
      else throw; 
     } 

    } 
} 
class CommonHandlers 
{ 
    public static void ArgumentHandler(Exception ex) 
    { 
     Console.WriteLine("Handling an argument exception"); 
    } 

    public static void DivZeroHandler(Exception ex) 
    { 
     Console.WriteLine("Please don't divide by zero. It upsets the universe."); 
    } 
} 
static class Program 
{ 

    private static void Main() 
    { 
     var ehd = new ExceptionHandledDelegate 
     { 
      codeBlock =() => { throw new ArgumentException("An argument exception has been thrown"); }, 
      ExceptionHandlers = new Dictionary<Type, ExceptionHandledDelegate.ExceptionCatcher> 
      { 
       {typeof (ArgumentException), CommonHandlers.ArgumentHandler}, 
       {typeof (DivideByZeroException),CommonHandlers.DivZeroHandler}, 
       {typeof (Exception), exception => Console.WriteLine("An exception has been thrown")} 
      } 
     }; 
     ehd.Run(); 
     ehd.codeBlock =() => { throw new Exception("An exception has been thrown"); }; 
     ehd.Run(); 
     ehd.codeBlock =() =>{var denom = 0; Console.WriteLine(100/denom);}; 
     ehd.Run(); 
     Console.ReadLine(); 
    } 
}