2014-01-30 65 views
1

考慮這個功能:「曖昧找到匹配」時,動態扔「System.ArgumentException」

static void Throw<T>(string message) where T : Exception 
{ 
    throw (T)Activator.CreateInstance(typeof(T), message, (Exception)null); 
} 

給定類型的System.ArgumentExceptionT,作爲問題標題說,我得找到「曖昧匹配的運行時錯誤」。看着爲ArgumentException的文件,以下是公共構造:

ArgumentException() 
ArgumentException(string) 
ArgumentException(SerializationInfo, StreamingContext) 
ArgumentException(string, Exception) 
ArgumentException(string, string) 
ArgumentException(string, string, Exception) 

鑑於我傳遞到CreateInstance 2個參數,並迫使null是空Exception,我努力理解爲什麼它是不匹配上面列表中的第4個構造函數?

+0

爲什麼你不只是'拋出新DerivedException(.. )'而不是調用這個'Throw '方法。除了污染你的調用堆棧外,它似乎沒有增加任何價值。 –

+0

@JakubKonecki,實際上'Throw'是'bool'上的擴展方法。如果(y&z)拋出blah2',有很多代碼是'if(x)throw blah''。擴展方法使這個更清潔,並且(個人)我沒有發現過度污染的調用堆棧,因爲我們知道在哪裏尋找。 –

回答

3

,將工作:

static void Throw<T>(String message) 
    where T: Exception { // <- It's a good style to restrict T here 

    throw (T) typeof(T).GetConstructor(new Type[] {typeof(String)}).Invoke(new Object[] {message}); 
} 

典型Exception具有以上的構造函數,所以我們寧願指出我們要執行哪一個。通常情況下,我們必須檢查是否有一個合適的構造函數:

static void Throw<T>(String message) 
    where T: Exception { // <- It's a good style to restrict T here 

    // The best constructor we can find 
    ConstructorInfo ci = typeof(T).GetConstructor(new Type[] {typeof(String)}); 

    if (!Object.ReferenceEquals(null, ci)) 
    throw (T) ci.Invoke(new Object[] {message}); 

    // The second best constructor 
    ci = typeof(T).GetConstructor(new Type[] {typeof(String), typeof(Exception)}); 

    if (!Object.ReferenceEquals(null, ci)) 
    throw (T) ci.Invoke(new Object[] {message, null}); 
    ... 
} 

然而,在你的情況,你可以把它與Activator

static void Throw<T>(String message) 
    where T: Exception { // <- It's a good style to restrict T here 

    throw (T) Activator.CreateInstance(typeof(T), message); 
} 
+0

欲瞭解更多信息,第二位的代碼是我*使用*具有的。然而,我的派生異常(好或壞 - 你可以是裁判),有'(字符串消息,異常內部= null)',它給出了一個'MissingMethod'異常的構造函數(因爲默認參數),因此爲了解決這個問題,增加了'null'。 –

+0

另外,在實際的代碼中,它受* where語句的限制,但是無論如何已經修改了原始問題。 –

+0

@JakubKonecki,我想你的意思是把這個評論放在其他答案:) –

1

這可能會實現

static void Throw<T>(string message) 
{ 
    Exception ex = null; 
    throw (Exception)Activator.CreateInstance(typeof(T), message, ex); 
} 

我不知道在哪裏Exception是這個名單上,但我的猜測是它是具體爲string,否則就不會是一個問題。 How does the method overload resolution system decide which method to call when a null value is passed?

+0

正如我在嘗試之前所懷疑的那樣,這會產生完全相同的問題。 –

+0

+1鏈接到埃裏克的答案。 –