2010-10-28 11 views
5

Si consideri il seguente codice che sto usando quando si visualizza l'indirizzo postale di un cliente all'interno di una tabella in una visualizzazione:ASP.NET MVC/C#: Posso evitare di ripetermi in una dichiarazione condizionale C# di una riga?

<%: Customer.MailingAddress == null ? "" : Customer.MailingAddress.City %> 

mi ritrovo con una discreta quantità di queste istruzioni condizionali ternari e mi chiedo se non v'è un modo per fare riferimento all'oggetto da valutare nella condizione in modo che io possa usarlo nell'espressione. Qualcosa del genere, forse:

<%: Customer.MailingAddress == null ? "" : {0}.City %> 

Esiste qualcosa del genere? So che posso creare una variabile per mantenere il valore, ma sarebbe bello tenere tutto dentro una piccola e stretta affermazione nelle pagine di visualizzazione.

Grazie!

risposta

2

No, non c'è un modo per fare esattamente quello che stai chiedendo senza creare una variabile o duplicare te stesso, anche se si può fare qualcosa di simile:

(Customer.MailingAddress ?? new MailingAddress()).City ?? string.Empty 

Ciò presuppone che un nuovo MailingAddress avrà città è immobile/campo Null per impostazione predefinita.

L'ultima coalescenza nulla può essere rimossa se la creazione di un nuovo MailingAddress inizializza il campo/la proprietà della città alla stringa vuota.

Ma questo non è effettivamente più breve, ed è più hacker (a mio parere), e quasi sicuramente meno performante.

+2

+1 Non perché lo userei, ma mi piace come usa il concatenamento :-) –

+2

Non penso che funzionerà effettivamente per fare ciò che l'OP vuole. non è nullo, quindi il risultato dell'istruzione è l'oggetto Customer.MailingAddress, ma l'utente desidera che la proprietà City dell'oggetto non sia l'oggetto stesso. –

+1

@Adam Porad. Non è vero. Il risultato ** del primo Paren Block ** è sempre un MailingAddress dereferenziabile. Otteniamo quindi la proprietà/il campo Città di quel MailingAddress (e null si coalesce se necessario). – McKay

2

È possibile utilizzare l'operatore ?? per il confronto con null.

Customer.MailingAddress == null ? "" : Customer.MailingAddress; 

di cui sopra può essere riscritta come segue:

Customer.MailingAddress ?? ""; 

Nel tuo caso genere creo metodo di estensione:

public static TValue GetSafe<T, TValue>(this T obj, Func<T, TValue> propertyExtractor) 
where T : class 
{ 
    if (obj != null) 
    { 
     return propertyExtractor(obj); 
    } 

    return null; 
} 

e l'uso sarebbe come questo:

Customer.GetSafe(c => c.MailingAddress).GetSafe(ma => ma.City) ?? string.Empty 
+0

L'operatore null coalescente non sarebbe pratico qui. –

+0

Risposta aggiornata. –

+0

Tutto il rispetto per una soluzione innovativa, ma questo è un sacco di overhead (e sintassi arcana) per evitare la ripetizione di un nome di tipo in un operatore condizionale ... –

2

Perché non creare una proprietà sull'oggetto Cliente che contiene tale condizione e chiamarla direttamente? vale a dire

Customer.FormattedMailingAddress 

che avrei scritto il codice, ma io sono sul mio cellulare, avresti solo bisogno di mettere la stessa condizione all'interno del get{} però.

+0

Concordo sul fatto che questo è un buon approccio, mi stavo chiedendo se ciò che stavo chiedendo fosse possibile o meno per esempi in cui non vorrei aggiungere una proprietà aggiuntiva. –

+0

Per il mio progetto (.net4 e mvc2) seguiamo lo schema che ho descritto e facciamo tutto questo (visualizzazione della formattazione della stringa) sugli oggetti stessi. Mi piace essere in grado di chiamare una proprietà da una vista e non preoccuparsi di alcuna logica non necessaria (affatto) nelle viste stesse. È una questione di gusti, e spero che il mio suggerimento aiuti almeno. – Dave

+0

Devo anche dire che ciò significa che quando una proprietà viene utilizzata in più viste, mantiene la stessa 'formattazione' (cioè su una pagina sviluppata nell'arco di un anno, non usa una logica diversa, producendo una stringa diversa, per lo stesso campo, a meno che non sia intenzionale :)) – Dave

1

Sono d'accordo con @Dave, creare un'estensione per la classe Cliente.

Qualcosa di simile a questo:

public static class CustomerExtension 
{ 
    public static string DisplayCity(this Customer customer) 
    { 
     return customer.MailingAddress == null ? String.Empty : customer.MailingAddress.City 
    } 
} 

Quindi è possibile chiamare il metodo come questo:

myCustomer.DisplayCity(); 

(nota: le estensioni non possono essere creati come una proprietà, quindi questo avrebbe dovuto essere un metodo.vedi Does C# have extension properties? per maggiori dettagli)

1

si potrebbe creare un metodo di estensione per ottenere il valore o restituire una stringa vuota:

public static string GetValue<T>(this T source, Func<T, string> getter) 
    { 
     if (source != null) 
      return getter(source); 

     return ""; 
    } 

poi chiamarlo:

<%: Customer.MailingAddress.GetValue(x=>x.City) %> 

Questo potrebbe funzionare per qualsiasi oggetto .

Problemi correlati