2011-12-20 62 views
1

我創建一個異常類這樣的:如何避免在以下代碼中強制轉換爲(ServiceException)?

public class ServiceException : ApplicationException { 

    public Dictionary<string, string> Errors { get; set; } 

    public ServiceException(Exception ex) : base("Service Exception", ex) { 
     Errors = new Dictionary<string, string>(); 
    } 
    public ServiceException() : this(null) {} 

} 

下面的代碼失敗:

protected void log(Exception ex) 
{ 
    if (ex is ServiceException) 
    { 
     var y = (ServiceException) 
     ModelState.Merge(ex.Errors); 
    } 
    else 
    { 
     Trace.Write(ex); 
     ModelState.AddModelError("", "Database access error: " + ex.Message); 
    } 
} 

它生成上編譯以下錯誤:

錯誤5 'System.Exception的'不包含「錯誤」 的定義,並且沒有接受 類型的第一個參數的擴展方法'Errors''System.Exception'c烏爾德找到(是否缺少using指令 或程序集引用?)

我通過以下操作固定它:

if (ex is ServiceException) 
{ 
    var y = (ServiceException)ex; 
    ModelState.Merge(y.Errors); 
} 

有一些辦法,我可以使用避免這種亂碼一個變量y然後鑄造它?沒有聲明中間變量y,代碼不會通過語法檢查。

+2

你需要口齒不清講:ModelState.Merge(((ServiceException)除息).Errors); – 2011-12-20 04:45:28

+0

在C#中,一種方法或者你必須使用一個強制轉換來使編譯器感到高興。 – Roman 2011-12-20 04:47:02

回答

2

您需要投射,因爲ex不是ServiceExceptionis運算符只是簡單地評估它是否爲ServiceException,但不會對該類型執行轉換。

想想ex是什麼類型。它的類型是Exception,一般來說你不知道它是什麼。通過調用ex is ServiceException,您正在檢查ex的動態類型是否爲ServiceException。但靜態類型仍然是Exception。這並沒有改變。

C#是一種靜態類型語言,所以你用is操作後靜態ex,這是Exception不會魔術般地變成ServiceException。你仍然需要自己施放它。

相反,你可能希望使用的運營商:

protected void log(Exception ex) 
{ 
    ServiceException se = ex as ServiceException; 
    if (se != null) 
     ModelState.Merge(se.Errors); 
    else 
    { 
     Trace.Write(ex); 
     ModelState.AddModelError("", "Database access error: " + ex.Message); 
    } 
} 

ex as ServiceException嘗試投exServiceException。如果ex不是ServiceException,則轉換失敗並返回null。

或者,如果你真的對使用額外的局部變量,那麼你可以只投它,然後立即使用它:

if (se is ServiceException) 
    ModelState.Merge(((ServiceException) se).Errors); 

老實說,雖然,我不明白你爲什麼會想這雖然。首先執行檢查(使用asis),然後使用經過降級的異常,這是此處最好的辦法。實際使用額外的變量更清晰,因爲您顯示了您的意圖,並且立即顯而易見您想要實現的目標。

1

你需要投它,但你可以只是做內聯:

if (ex is ServiceException) 
     { 
      ModelState.Merge(((ServiceException)ex).Errors); 
     } 

希望幫助:)

0

你將不得不投,只是說我會做不同的看法。

try 
    { 
    ... 
    } 
    catch(ServiceException ex) 
    { 
     logException(ex); 
    } 
    catch(Exception ex) 
    { 
     logException(ex); 
    } 

public void logException(ex) 
{ 
    if(ex is ServiceException) 
    { 
     logServiceException(ex as ServiceException) 
    } 
    else 
    { 
     logGenericException(ex) 
    } 
} 

private void logGenericException(Exception ex) 
{ 
... 
} 

沒有必要在下面的方法來投

private void logServiceException(ServiceException ex) 
    { 
    //now there is no need to do a cast 
    } 
相關問題