Come usare la parola chiave di stile Java in C #?

In Java, la parola chiave throws consente a un metodo di dichiarare che non gestirà un’eccezione da sola, ma piuttosto di lanciarla al metodo chiamante.

C’è una parola chiave / attributo simile in C #?

Se non c’è un equivalente, come si può ottenere lo stesso effetto (o un effetto simile)?

In Java, devi gestire un’eccezione o contrassegnare il metodo come uno che può lanciarlo usando la parola chiave throws .

C # non ha questa parola chiave o una equivalente, come in C #, se non gestisci un’eccezione, essa si riempie di bolle, finché non viene catturata o, se non presa, interromperà il programma.

Se vuoi gestirlo e poi rilanciare, puoi fare quanto segue:

 try { // code that throws an exception } catch(ArgumentNullException ex) { // code that handles the exception throw; } 

L’op sta chiedendo l’ equivalente C # della clausola di throws di Java – non la parola chiave throw . Questo viene utilizzato nelle firme dei metodi in Java per indicare che è ansible generare un’eccezione verificata.

In C # non esiste un equivalente diretto di un’eccezione controllata di Java. C # non ha una clausola di firma del metodo equivalente.

 // Java - need to have throws clause if IOException not handled public void readFile() throws java.io.IOException { ...not explicitly handling java.io.IOException... } 

si traduce in

 // C# - no equivalent of throws clause exceptions are unchecked public void ReadFile() { ...not explicitly handling System.IO.IOException... } 

Sì, questo è un vecchio thread, tuttavia trovo spesso thread vecchi quando sono su google le risposte, quindi ho pensato di aggiungere qualcosa di utile che ho trovato.

Se si utilizza Visual Studio 2012, è disponibile uno strumento incorporato che può essere utilizzato per consentire un livello “gettato” IDE equivalente.

Se si utilizzano i commenti della documentazione XML , come menzionato sopra, è ansible utilizzare il tag per specificare il tipo di eccezione generata dal metodo o dalla class e le informazioni su quando o perché viene generato.

esempio:

  /// This method throws an exception. /// A path to a directory that will be zipped. /// This exception is thrown if the archive already exists public void FooThrowsAnException (string myPath) { // This will throw an IO exception ZipFile.CreateFromDirectory(myPath); } 

Ecco una risposta a una domanda simile che ho appena finanziato su bytes.com :

La risposta breve è no, non ci sono eccezioni controllate in C #. Il designer della lingua discute questa decisione in questa intervista:

http://www.artima.com/intv/handcuffs.html

Il più vicino è ansible utilizzare i tag nella documentazione XML e distribuire i documenti generati da NDoc con il proprio codice / assiemi in modo che altre persone possano vedere quali eccezioni vengono lanciate (che è esattamente ciò che MS fa nella documentazione MSDN). Non puoi fare affidamento sul compilatore per informarti sulle eccezioni non gestite, tuttavia, come potresti essere abituato a java.

In realtà non aver controllato le eccezioni in C # può essere considerato una cosa buona o ctriggers.

Io stesso ritengo che sia una buona soluzione poiché le eccezioni controllate forniscono i seguenti problemi:

  1. Eccezioni tecniche che sfuggono allo strato business / dominio perché non è ansible gestirle correttamente a basso livello.
  2. Appartengono alla firma del metodo che non sempre è piacevole con il design dell’API.

Per questo motivo nella maggior parte delle applicazioni più grandi vedrai spesso il seguente schema quando spuntate Si verificano eccezioni:

 try { // Some Code } catch(SomeException ex){ throw new RuntimeException(ex); } 

Che essenzialmente significa emulare il modo in cui C # /. NET gestisce tutte le eccezioni.

Esistono alcune fugaci somiglianze tra .Net EnsuresOnThrow<> e il java EnsuresOnThrow<> descrittore, in quanto entrambi possono segnalare al chiamante il tipo di eccezione che potrebbe essere generato da una funzione o da un metodo, anche se ci sono anche grandi differenze tra 2:

  • EnsuresOnThrow<> va oltre la semplice indicazione di quali eccezioni possono essere lanciate, ma stabilisce anche le condizioni in base alle quali è garantito che vengano lanciate: questo può essere un codice abbastanza oneroso nel metodo chiamato se la condizione di eccezione non è banale da identificare. I throws Java forniscono un’indicazione di quali eccezioni potrebbero essere lanciate (cioè IMO l’attenzione su .Net è all’interno del metodo che si contrae per dimostrare il throw , mentre in Java l’attenzione si sposta sul chiamante per riconoscere la possibilità dell’eccezione).
  • .Net CC non fa la distinzione tra eccezioni Checked vs Unchecked che Java ha, sebbene la sezione 2.2.2 del manuale CC faccia riferimento a

“Utilizzare postcondizioni eccezionali solo per quelle eccezioni che un chiamante dovrebbe aspettarsi come parte dell’API”

  • In .Net il chiamante può decidere se fare o meno qualcosa con l’eccezione (ad es. Disabilitando i contratti). In Java, il chiamante deve fare qualcosa , anche se aggiunge una throws per la stessa eccezione sulla sua interfaccia.

Manuale dei contratti di codice qui

Dopo aver esaminato la maggior parte delle risposte qui, vorrei aggiungere un paio di pensieri.

  1. Affidarsi ai commenti della documentazione XML e aspettarsi che gli altri facciano affidamento è una scelta sbagliata. La maggior parte del codice C # che ho incontrato non documenta i metodi in modo completo e coerente con i commenti della documentazione XML. E poi c’è il problema più grande che senza le eccezioni controllate in C #, come potresti documentare tutte le eccezioni che il tuo metodo genera per il tuo utente API per sapere come gestirle tutte individualmente? Ricorda, conosci solo quelli che ti lanci con la parola chiave throw nella tua implementazione. Le API che stai utilizzando all’interno dell’implementazione del tuo metodo potrebbero anche generare eccezioni di cui non sei a conoscenza perché potrebbero non essere documentate e non le gestirai durante l’implementazione, quindi esploderanno di fronte al chiamante della tua metodo. In altre parole, questi commenti alla documentazione XML non sostituiscono le eccezioni controllate.

  2. Andreas ha collegato un’intervista con Anders Hejlsberg nelle risposte qui sul perché il team di progettazione C # ha deciso di non controllare le eccezioni. L’ultima risposta alla domanda originale è nascosta in quell’intervista:

I programmatori proteggono il loro codice scrivendo try finally’s dappertutto, quindi usciranno correttamente se si verifica un’eccezione, ma in realtà non sono interessati a gestire le eccezioni.

In altre parole, nessuno dovrebbe essere interessato a quale tipo di eccezione può essere prevista per una particolare API, dato che le catturerai sempre tutte. E se vuoi davvero preoccuparti di particolari eccezioni, come gestirle dipende da te e non qualcuno che definisce una firma di metodo con qualcosa come la parola chiave Java throw, forzando una particolare gestione delle eccezioni su un utente API.

Personalmente, sono strappato qui. Sono d’accordo con Anders che avere controllato le eccezioni non risolve il problema senza aggiungere nuovi, diversi problemi. Proprio come con i commenti della documentazione XML, raramente vedo il codice C # con tutto ciò che è racchiuso in try finally blocks. Mi sembra che questa sia davvero la tua unica opzione e qualcosa che sembra una buona pratica.

Stai chiedendo questo:

Rilanciare un’eccezione

 public void Method() { try { int x = 0; int sum = 100/x; } catch(DivideByZeroException e) { throw; } } 

o

 static void Main() { string s = null; if (s == null) { throw new ArgumentNullException(); } Console.Write("The string s is null"); // not executed }