2010-10-21 18 views
7

quando si implementano/utilizzano metodi che restituiscono o funzionano con istanze di oggetti, qual è l'approccio più elegante per verificare i parametri della funzione?Il modo migliore per verificare i parametri delle funzioni: Verifica null o try/catch

metodo da chiamare:

someType GetSomething(object x) 
{ 
    if (x == null) { 
     return; 
    } 

    // 
    // Code... 
    // 
} 

o meglio:

someType GetSomething(object x) 
{ 
    if (x == null) { 
     throw new ArgumentNullException("x"); 
    } 

    // 
    // Code... 
    // 
} 

metodo di chiamata:

void SomeOtherMethod() 
{ 
    someType myType = GetSomething(someObject); 

    if (someType == null) { 
     return; 
    } 

} 

o meglio:

void SomeOtherMethod() 
{ 
    try { 
     someType myType = GetSomething(someObject); 
    } catch (ArgumentNullException) { 
    } 
} 

Quando si sfogliano domande simili, il motivo per non utilizzare try/catch è la prestazione. Ma IMHO il try-catch sembra solo meglio :).

Quindi, da che parte è più "elegante"?

risposta

8

Se passando un null non è valido, un'eccezione (vale a dire - si tratta di una situazione eccezionale che mai dovrebbe accadere).

Se un parametro nullè valido, restituire un oggetto corrispondente.

In generale, accettando null parametri è cattiva pratica - va contro il principio di minima sorpresa e richiede al chiamante di sapere è valida.

+0

Avere funzioni che valuteranno input non nulli e restituire null per input nulli, è spesso uno schema utile. In alcuni casi, il pattern Null Object può essere più bello, ma può essere difficile da implementare con i generici. – supercat

2

È consigliabile utilizzare eccezioni solo per casi eccezionali. Se ti aspetti che l'argomento possa essere (legittimamente) nullo, dovresti controllarlo - non usare eccezioni per questo. IMO si dovrebbe verificare per null sul sito di chiamata (prima del invocazione) se non ha senso passare null al metodo.

0

Nell'esempio GetSomthing è privato. Ciò significa che puoi rintracciare tutti i chiamanti e assicurarti che i valori Null non vengano trasmessi, ad es.

if (x != null) 
    someType myType = GetSomthing(x) 
else 
    // Initialize x or throw an InvalidOperation or return whatever is correct 

Tuttavia, se non è proprio privato, si dovrebbe fare come Oded e altri hanno detto. Verifica se è nullo e genera un ArguementExecption nella maggior parte dei casi.

4

Per quanto riguarda l'eleganza, è difficile top Code Contracts.

Contract.Requires(x != null);