2015-10-27 46 views
1

System.Exception類有4個構造函數:爲什麼在C#Exception類沒有帶有1個異常參數的構造函數?

public Exception(); 
public Exception(string message); 
protected Exception(SerializationInfo info, StreamingContext context); 
public Exception(string message, Exception innerException); 

爲什麼它沒有這個構造?

public Exception(Exception innerException); 


這是一個地方,這將是有幫助的。

我有一個靜態方法來得到一個開放的連接:

public static DbConnection GetOpenConnection(string dataProvider, string connectionString) 
{ 
    DbConnection dbConnection = GetDbProviderFactory(dataProvider).CreateConnection(); 
    dbConnection.ConnectionString = connectionString; 
    dbConnection.Open(); 
    return dbConnection; 
} 

我想這個方法拋出一個自定義異常GetOpenConnectionException如果有錯誤發生。

因此,我創建了自定義異常GetOpenConnectionException

public class GetOpenConnectionException : Exception 
{ 
    public GetOpenConnectionException(string message) : base(message) 
    { 
    } 
    public GetOpenConnectionException(string message, Exception innerException) : base(message, innerException) 
    { 
    } 
} 

由於Exception沒有構造public Exception(Exception innerException),我不能有這樣的代碼在GetOpenConnectionException

public GetOpenConnectionException(Exception innerException) : base(innerException) 
{ 
} 

所以我不得不來編碼GetOpenConnection()這種方法:

public static DbConnection GetOpenConnection(string dataProvider, string connectionString) 
{ 
    try 
    { 
     DbConnection dbConnection = GetDbProviderFactory(dataProvider).CreateConnection(); 
     dbConnection.ConnectionString = connectionString; 
     dbConnection.Open(); 
     return dbConnection; 
    } 
    catch (Exception e) 
    { 
     throw new GetOpenConnectionException("", e); 
    } 
} 

我想要的東西是這樣的編碼方法GetOpenConnection()

public static DbConnection GetOpenConnection(string dataProvider, string connectionString) 
{ 
    try 
    { 
     DbConnection dbConnection = GetDbProviderFactory(dataProvider).CreateConnection(); 
     dbConnection.ConnectionString = connectionString; 
     dbConnection.Open(); 
     return dbConnection; 
    } 
    catch (Exception e) 
    { 
     throw new GetOpenConnectionException(e); 
    } 
} 

這是否有道理?

+4

任何原因,你不能只是做'public GetOpenConnectionException(Exception innerException):base(「」,innerException)'' –

+4

基本上你只是在另一個異常中包裝一個異常,添加一條消息有助於說明爲什麼要包裝它,否則只是重新拋出內部異常。如果您沒有爲異常增加價值,請不要包裝它。 –

+0

通過在此處重新拋出異常,您獲得了什麼? –

回答

1

其他答案提供了很好的方法來實現你所要求的,但我相信你的問題的核心是:「爲什麼這不存在呢?」

當例程關於它使用的資源的假設或先決條件以及它所要求的參數未得到滿足時,通常會拋出異常。拋出的異常應該有助於調用者(或程序員)理解不符合什麼假設或先決條件,以便他們能夠相應地處理或修復他們的代碼。該信息是該通信的重要組成部分。我甚至會冒險猜測,如果Exception類不需要可序列化,那甚至不會有空的構造函數!

在另一個嵌套異常意味着嵌套的異常是容器異常的原因。 (Exception類的特定構造函數的documentation指向了這一點。)如果僅僅傳遞一個沒有任何消息的內部異常,就會有效地轉化爲「我將拋出一個異常,除了它的類型外,它不提供額外的信息。「這不是非常有幫助,它很可能已經更好簡單地讓原來的異常被拋出

這裏是你能提供一個更有意義的信息的一種方式。

public static DbConnection GetOpenConnection(string dataProvider, string connectionString) 
{ 
    try 
    { 
     DbConnection dbConnection = GetDbProviderFactory(dataProvider).CreateConnection(); 
     dbConnection.ConnectionString = connectionString; 
     dbConnection.Open(); 
     return dbConnection; 
    } 
    catch (Exception e) // consider changing this to a more specific type of exception, as an error with .Open() is not the only way it could fail 
    { 
     // provide a meaningful message to the caller about the context of this error 
     var message = string.Format("An error occurred while trying to connect to the data provider {0} with the connection string {1}.", dataProvder, connectionString); 
     throw new GetOpenConnectionException(message, e); 
    } 
} 
+0

謝謝。 「爲什麼這首先不存在?」真的是我的問題,你已經完全回答了。 – ChumboChappati

4
public GetOpenConnectionException(Exception innerException) : base("", innerException) 
    { 
    } 
+4

雖然此代碼可能會回答問題,但爲何和/或代碼如何回答問題提供了其他上下文,這可以提高其長期價值。 – ryanyuyu

+0

在此清除異常消息。如果你試圖獲得ex.Message,你總會得到一個空字符串。 – CharithJ

+0

也許':base(null,innerException)'更好? –

0

到彼得·多瑞的回答一樣,你可以這樣做:

public GetOpenConnectionException(Exception innerException) : 
    base(innerException.message, innerException) 
{ 
} 

這樣你實際上是通過一些有意義的東西到基本構造。

至於爲什麼沒有一個構造函數只接受一個Exception參數......它似乎並不是一個很好的理由。他們很容易擁有。

相關問題