2010-05-17 12 views
7

Se ho una routine che può gettare un ArgumentException in due punti, qualcosa di simile ...Quale delle due eccezioni è stata chiamata?

if (Var1 == null) 
{ 
    throw new ArgumentException ("Var1 is null, this cannot be!"); 
} 

if (Val2 == null) 
{ 
    throw new ArgumentException ("Var2 is null, this cannot be either!"); 
} 

Qual è il modo migliore di determinare nella mia routine chiamante quale delle due eccezioni è stato gettato?

O

sto facendo questo in modo sbagliato?

risposta

11

Passa il nome della variabile (Val1, Val2 ecc.) Nel secondo argomento al costruttore ArgumentException. Questa diventa la proprietà ArgumentException.ParamName.

4

La funzione di chiamata non dovrebbe preoccuparsi di quale linea ha causato l'eccezione. In entrambi i casi è stato generato uno ArgumentException ed entrambi devono essere gestiti allo stesso modo.

+0

+1 Anche questo potrebbe essere facilmente controllato prima di chiamare il metodo. – Skurmedel

+0

ma se volessi visualizzare un messaggio specifico all'utente a seconda di quale delle due eccezioni è stata lanciata? – Rob

+0

È possibile utilizzare il testo dall'eccezione stessa oppure lanciare 'ArgumentNullException'. –

12

Per questo scenario specifico si dovrebbe usare ArgumentNullException e riempire correttamente la sua proprietà ParamName in modo da conoscere l'argomento che è nullo.

La classe ArgumentException supporta anche la stessa proprietà ma è necessario utilizzare il tipo di eccezione più specifico disponibile.

Quando si utilizzano questi tipi di eccezioni, prestare attenzione quando si utilizza il costruttore che accetta sia il messaggio sia il nome del parametro. Gli ordini vengono commutate tra ogni tipo di eccezione:

throw new ArgumentException("message", "paramName"); 

throw new ArgumentNullException("paramName", "message"); 
0
try 
     { 
      //code here 
     } 
     catch (ArgumentException ae) 
     { 
      Console.WriteLine(ae.ToString()); 
     } 

L'output nella console vi dirà il messaggio che hai messo.

3

Utilizzare il costruttore ArgumentException(string, string) per definire quale parametro era nullo.

if (Var1 == null) { 
    throw new ArgumentException ("Var1 is null, this cannot be!","Var1"); 
} 

if (Val2 == null){ 
    throw new ArgumentException ("Var2 is null, this cannot be either!","Var2"); 
} 
2

Beh, per un ArgumentException, in particolare, si dispone di un parametro per il quale argomento aveva un problema:

throw new ArgumentException("Var1 is null, this cannot be!", "Var1"); 

In senso più generale, di solito si farebbe qualcosa di simile uso diverso (possibilmente personalizzato) tipi di eccezioni, e quindi il codice chiamante può avere diversi blocchi di cattura

public class MyCustomException1 : ApplicationException {} 
public class MyCustomException2 : ApplicationException {} 


try 
{ 
DoSomething(); 
} 
catch(MyCustomException1 mce1) 
{ 
} 
catch(MyCustomException2 mce2) 
{ 
} 
catch(Exception ex) 
{ 
} 
+0

In questa situazione il secondo argomento di ArgumentException dovrebbe essere una stringa, ovvero il nome del parametro offendente. – Polyfun

+0

whoops ... certo che hai ragione – Clyde

3

La domanda più grande che dovreste porvi voi stessi è perché? Se stai cercando di eliminare una qualche logica, le eccezioni sono in genere un modo sbagliato.

Piuttosto, dovresti avere un tipo di ritorno (o un parametro out/ref) che verrà impostato con un flag/valore di qualche tipo che puoi rilevare dal codice chiamante per determinare quale sia l'errore e far scattare la tua logica quella.

Se si desidera utilizzare eccezioni, in questo caso, lo ArgumentNullException has a constructor that takes the name of the parameter and the exception message. È possibile generare l'eccezione e quindi quando si rileva l'eccezione, accedere a ParamName property per determinare il nome del parametro che ha causato l'eccezione.

0

Quando si lancia ArgumentExceptions è sempre possibile includere il nome dell'argomento che causa l'eccezione (è another constructor).Naturalmente suppongo che tu voglia veramente sapere quale era nullo e in tal caso dovresti probabilmente usare lo ArgumentNullException.

0

Se si tratta di un caso di test in cui si desidera assicurarsi che venga visualizzato il messaggio di eccezione corretto, so che NUnit ha una parola chiave ExpectedMessage nell'attributo ExpectedException. Altrimenti, un ArgumentNullException è un ArgumentNullException e la tua applicazione dovrebbe trattarli tutti uguali. Se vuoi maggiori dettagli, crea le tue classi di eccezione e usale.

Così si potrebbe verificare il seguente:

[ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Var1 is null, this cannot be!"] 
public void TestCaseOne { 
    ... 
} 

[ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Var2 is null, this cannot be either!"] 
public void TestCaseTwo { 
    ... 
} 
3

In realtà non fornire informazioni sufficienti per rispondere alla tua domanda. La risposta ovvia è guardare il messaggio dell'eccezione, ma suppongo che non sia quello che stai cercando.

Se è davvero importante distinguerli in modo programmatico, utilizzare un'altra eccezione o almeno utilizzare la proprietà paramName del costruttore dell'eccezione corrente. Questo ti darà informazioni un po 'più rilevanti.

Tuttavia, l'utilizzo del proprio tipo di eccezione è l'unico modo per garantire che si stia rilevando l'eccezione per una particolare circostanza. Poiché ArgumentException fa parte del framework, è possibile che qualcun altro che chiami possa lanciarlo, il che ti porterà nello stesso blocco catch. Se crei il tuo tipo di eccezione (uno per entrambi o uno per ciascuno degli scenari), questo ti fornirà un modo per gestire l'errore specifico. Naturalmente, a giudicare dal tuo esempio, sembra che sarebbe più semplice controllare e vedere se Val1 o Val2 è nullo prima di chiamare la funzione per iniziare.

Problemi correlati