2009-02-17 12 views
5

Nei linguaggi funzionali c'è spesso un monad Maybe che consente di concatenare più chiamate su un oggetto e restituire l'intera espressione None/null se nessuna parte della catena restituisce nulla, piuttosto che il tipico NullReferenceException che si ottiene C# concatenando le chiamate in cui un oggetto potrebbe essere nullo.Un operatore di de-riferimento condizionale sarebbe una buona cosa in C#?

Questo può essere banalmente implementato crei una Maybe<T> con alcuni metodi di estensione per consentire comportamento simile in C# utilizzando comprehensions query, che può essere utile quando si elaborano XML con elementi facoltativi/attributi esempio

var val = from foo in doc.Elements("foo").FirstOrDefault().ToMaybe() 
      from bar in foo.Attribute("bar").ToMaybe() 
      select bar.Value; 

Ma questa sintassi è un po 'goffo e poco intuitivo come le persone sono abituate a trattare con le sequenze in LINQ, piuttosto che singoli elementi, e ti lascia con un Maybe<T> piuttosto che un T alla fine. Un operatore di de-riferimento condizionale (ad es. ..) sarebbe sufficientemente utile per farlo entrare nella lingua? per esempio.

var val = doc.Elements("foo").FirstOrDefault()..Attribute("bar")..Value; 

Il condizionale de-riferimento si espanderebbe a qualcosa di simile:

object val; 
var foo = doc.Elements("foo").FirstOrDefault(); 
if (foo != null) 
{ 
    var bar = foo.Attribute("bar"); 
    if (bar != null) 
    { 
     val = bar.Value; 
    } 
    else 
    { 
     val = null; 
    } 
} 

posso vedere che questo potrebbe potenzialmente portare a terribili abusi come l'utilizzo di .. ovunque per evitare una NullReferenceException, ma d'altra parte se usato correttamente potrebbe essere molto utile in diverse situazioni. Pensieri?

+0

Mi piace l'idea, molto. Suggerisco caldamente di usare qualcos'altro thean '..'. Forse '??.'. In ogni caso, qualcosa che non è un singolo errore di battitura lontano da '.'. –

risposta

1

Concatenare più chiamate su un oggetto mi fa temere violazioni dello Law of Demeter. Pertanto, sono scettico sul fatto che questa funzione sia una buona idea, almeno in termini di risoluzione del problema specifico che stai usando come esempio.

+0

Ho scelto l'esempio XML in modo specifico per mostrare una situazione in cui è virtualmente impossibile * non * violare questa legge mentre si fa qualcosa di utile, dato che XML è una struttura ad albero ben documentata in cui non ritengo che questa legge sia realmente applicabile. –

+0

Il problema con la legge di Demeter è che qualcuno lo ha chiamato "Law of Demeter" piuttosto che "Guideline of Demeter" che è quello che è. Le linee guida sono lì per guidarci, ma non devono ostacolare una buona idea. –

+0

Vorrei rispondere che questo è ciò che xpath è per ma posso vedere dove una stringa pura sarebbe considerata più brutta da alcuni. Detto questo, il più delle volte questo NON è qualcosa che vuoi fare. – Brian

0

È un'idea interessante che è possibile ottenere con un metodo di estensione. Qualcosa di simile, per esempio (si noti, solo per esempio - sono sicuro che può essere raffinato):

public static IEnumerable<T> Maybe<T>(this IEnumerable<T> lhs, Func<IEnumerable<T>, T> rhs) 
{ 
    if (lhs != null) 
    { 
    return rhs(lhs); 
    } 

    return lhs; 
} 
0

Ho il sospetto che una combinazione di Nullable e metodi di estensione permetterebbe una porzione significativa di questo a B raggiunto.

Ciò limiterà T a tipi di valore, naturalmente.

(TBH Avrei preferito vedere il supporto tuple nel langauge ed eliminare i punti principali, come F # fa.)

codice è possibile essere semplificata, impostare val di nulla e si eliminano i rami altro.

-2

Posso vedere l'utilità potenziale, ma a parte un leggero impatto sulle prestazioni se gli elementi sono spesso nulli, perché non circondare semplicemente il blocco di codice con un blocco try..catch per una NullReferenceException?

+0

Il problema con l'utilizzo di try/catch è il fatto che ti allontana dalla query. Con un'operazione che gestisce null, la query può completare e fornire un risultato valido, che potrebbe essere molto utile se si hanno varie espressioni nella query. –

+0

Le eccezioni per il controllo del flusso non sono praticamente mai una buona idea ... Non entrerò nel motivo per cui qui; ci sono molte informazioni su questo sito e su internet in generale su questo. –

+0

Ah, ho avuto l'impressione che non sarebbe arrivato alcun risultato valido se una delle parti della query ha restituito null - semplicemente non avrebbe generato un errore. Per quanto riguarda l'utilizzo di Eccezioni per il controllo del flusso, sono d'accordo - ecco perché ho menzionato che gli elementi non sono spesso nulli. –

Problemi correlati