2009-10-07 47 views
1

以下是關於這個話題前兩個問題:C#中多類型catch塊的可能語法?

我今天的工作,並認爲這可能是一個合適的語法應該這個功能曾經被添加到C#語言。任何人對此有任何意見?

e的類型必須是列出的每種異常類型的基本類型或接口。

編輯:在這個例子中,捕捉塊處理要麼ArgumentNullExceptionArgumentOutOfRangeException,並將異常實例中稱爲eArgumentException類型的變量。它不處理除列出的兩個以外的任何其他類型的ArgumentException。我認爲,as的關聯性存在一些混淆。

編輯2:如果列出的例外所有上溯造型到的e類型的變量,則代碼完全編譯爲MSIL沒有任何鑄模或顯式的類型檢查,使其更快(潛在顯著)比當前語法如果它不是你想要的兩個之一,則捕獲ArgumentException後跟一個throw;。如果你抓到Exception並檢查兩種可能的類型來處理和重新投擲,如果它是別的東西,問題就更加明顯。

try 
{ 
} 
catch (ArgumentNullException, ArgumentOutOfRangeException as ArgumentException e) 
{ 
} 
+0

能否downvoters說他們爲什麼downvoted這題? – Dykam 2009-10-07 20:15:58

+1

唯一的問題是「任何人對此有任何意見?」。答案是:「是的,我們大多數人都是非常有見地的人。」要麼提出一個「真正」的問題,要麼是GTFO。 – abelenky 2009-10-14 21:49:37

+0

[另類,功能風格](http://community.bartdesmet.net/blogs/bart/archive/2008/01/06/exception-handling-in-functional-style.aspx):好吧,還不如干淨(作爲你的和其他許多建議)**,但這是有效的。** – nawfal 2013-05-18 11:17:36

回答

-1

這隻有在您不聲明實例(e)時纔有效。如果你在塊內引用e,它是什麼?

+0

'e'顯然是'ArgumentException',因爲正如我所說它的類型必須是每個列出的處理異常的基類型或接口。除了'ArgumentNullException'和'ArgumentOutOfRangeException'外,catch塊不會處理任何'ArgumentException'。我實際上特別提出了這個問題,因爲這個語法解決了你提到的問題。 – 2009-10-07 17:15:51

0

我不覺得自己很想在C#中經常使用它,而在Java中,我發現存在各種情況,我必須捕獲一堆檢查的異常,並將它們全部封裝在聲明我的方法的不同異常中扔。

東西我可能像一些語法:

try 
{ 
} 
wrap (OneException as AnotherException) 
catch (HandleableException e) 
{ 
    // Actual handling for some exception types 
} 

...但同樣,我發現自己這樣做比在C#更在Java中。

還有其他的增強功能,其中也一路上漲我名單爲C#這:)

+0

這不處理所有'ArgumentException's,只列出了兩個。 'as ArgumentException e'給出了'e'類型,這個類型保證與這個catch塊聲明處理的每一個可能的異常兼容。 – 2009-10-07 17:17:08

+0

你是編輯這個問題,還是我錯過了?我可以發誓,它之前只列出了三個例外。嗯 - 編輯:) – 2009-10-07 17:22:38

+0

我沒有編輯代碼,但我添加了兩個標記的段落,解釋了爲什麼這可能比當前更好。有一些API(是ASP.NET嗎?),它需要對許多不同類型的異常進行異常處理,而且我看到代碼變得非常冗餘,沒有簡單的方法來改進它。 – 2009-10-07 17:31:07

0

你已經可以做到這一點,只是

try{} 
catch(Exception e) 
{} 

,因爲所有的異常從System.Exception派生。你會像上面那樣做,確定catch塊本身的異常類型。

+0

這是缺乏此功能的解決方法,並且在我添加的鏈接中對此進行了專門討論。我在上面添加了** Edit 2 **,以解決爲此用例添加語言語法的一個主要好處。 – 2009-10-07 17:33:54

+0

Wokrarounds現在工作,您要等待多長時間才能添加語言功能?假設它會一直髮生? – 2009-10-07 17:39:58

+0

但這不是這個問題的關鍵。我已經知道如何處理可用的情況。語言隨着時間的推移而發展,呈現出人們所想的特徵。這可能永遠不會發生(功能接受的統計速率非常低),但至少對我來說這是需要思考的問題。 :) – 2009-10-07 19:20:12

3

看到這個:
Cool or Stupid? Catch(Exception[NamingException, CreateException] e)

我這個問題的答案是,他們應該讓你「堆棧」他們喜歡用塊:

try 
{ 
} 
catch (ArgumentNullException e) 
catch (ArgumentOutOfRangeException e) 
catch (ArgumentException e) 
{ 

} 

雖然我看你會爲而不是。我個人並不認爲方法非常有用,因爲您已經受限於真正的非接口異常類型,並且沒有雙重繼承。

+0

我喜歡這種方法,因爲它模仿如何堆疊病例陳述。只要編碼器願意根據需要確定catch塊中的類型。 – 2009-10-07 17:16:08

+0

檢查我的兩個編輯,再加上這並沒有解決「e」是什麼類型的問題。 – 2009-10-07 17:28:50

+0

我認爲這會起作用,但參數上的變量名應該是唯一的。 – 2009-10-07 17:33:22

0

如果ArgumentNullExceptionArgumentOutOfRangeException有不同的接口,將正確地蒙上了痛苦;

例如ArgumentOutOfRangeExceptionActualValue財產;如果你不得不使用它,你會喜歡的東西結束:


if(e is ArgumentOutOfRangeException) 
{ 
    // use e.ActualValue 
} 
else 
{ 
    // use e.Data 
} 
+0

這是針對每個處理的異常類型共享catch塊中的大部分或全部代碼的情況。 – 2009-10-07 17:32:19

1

納入這一功能的是planned對Java 7的語法如下:

try { 
    return klass.newInstance(); 
} catch (InstantiationException | IllegalAccessException e) { 
    throw new AssertionError(e); 
} 

編輯:我覺得目的是對於e的靜態類型來說,它是列出的異常的最具體的共同超類。 (在Java中,只有類java.lang.Throwable的實例可以被拋出,因此具有共同的超級接口趕上用途有限的,因爲異常不能被再次拋出。)

+0

該提案定義不明確,因爲它沒有解決向變量'e'提供靜態有效類型的主要問題。被處理的異常列表(在''後面用','和Java提議中的'|'分開)應該與異常變量聲明類型分開。我用'as'來清楚地區分兩者。 Java提議可以使用'as',或者'catch(InstantiationException | IllegalAccessException:VariableType e)',*必須*異常列表中的每種類型都可以轉換爲'VariableType'。 – 2009-10-07 22:06:25