2012-11-29 4 views
9

Abbiamo un tipo che ha un operatore di stringa implicito. Ecco come si presenta:Gli operatori impliciti gestiscono null?

public class Foo 
{ 
    readonly string _value; 

    Foo(string value) 
    { 
     _value = value; 
    } 

    public static implicit operator string(Foo foo) 
    { 
     return foo._value; 
    } 

    public static implicit operator Foo(string fooAsText) 
    { 
     return new Foo(fooAsText); 
    } 

} 

Abbiamo appena avuto uno scenario in cui l'istanza passata all'operatore implicito era null. Ovviamente, abbiamo finito con un NullReferenceException.

Ho pensato che fosse abbastanza giusto, dopotutto, qual è la rappresentazione di stringa di un tipo che è nullo - difficile da dire - quindi l'eccezione sembrava valida e qualcosa che non dovremmo intercettare/sopprimere/gestire/ignorare. Il mio ragionamento era sulla falsariga di "qualcuno mi ha dato un nulla, perché dovrei restituire null. Non lo faccio con altri metodi '. Ho pensato, 'Lo so, mi limiterò a verificare la presenza di null prima convertirlo', qualcosa come:

string s = foo == null ? null : foo;

Ma che non ha funzionato, perché è ora la conversione in una stringa prima il confronto con null. Naturalmente, questo confronto funzionerebbe:

Foo f = null; 
string s; 
if (f != null) 
{ 
    s = f; 
} 

... ma questo è solo brutto.

ho letto la sezione in Essential C# 5 4th edition (un libro 'Rough Cuts' su Safari) e si dice:

non gettare eccezioni conversioni implicite.

Questo dice di non tiro eccezioni, ma lascia che mi domando dovrei sopprimere eccezioni?

La cosa più ovvia da fare è fare un salto nel metodo e modificarla in:

public static implicit operator string(Foo foo) 
{ 
    return foo == null ? null : foo._value; 
} 

Problema risolto. Ma mi sento sporco. Mi sembra di nascondere un potenziale problema controllando la nullità. Sono paranoico/anale/stupido?

+1

tutto dipende dal tuo caso d'uso. vuoi che 'stringa' sia nullo? –

+1

Buon punto. Idealmente vorremmo non imbattersi mai in un'istanza null di un 'Foo'. Hmmm ... Forse dovrebbe essere una struttura ... –

+2

@SteveDunn: Una cosa importante: A 'NullReferenceException' indica sempre un bug nel codice che solleva l'eccezione, * non * nel chiamare il codice. Quindi semplicemente non controllare 'foo' per' null' è un bug nell'operatore. –

risposta

12

Quello che vorrei raccomandare in questo caso è che l'operatore che può fallire dovrebbe essere esplicito piuttosto che implicito. L'idea di una conversione implicita è che si sta allargando (vale a dire non fallirà mai.) Le conversioni esplicite, d'altra parte, sono intese a volte in grado di fallire.

+1

Ecco cosa consiglia anche la documentazione: http://msdn.microsoft.com/en-us/library/z5z9kes2.aspx –