2010-10-28 6 views
5

considere el siguiente código que estoy usando al mostrar la dirección postal de un cliente dentro de una tabla en una vista:ASP.NET MVC/C#: ¿Puedo evitar repetirme en una declaración condicional de una línea de C#?

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

me encuentro con una cantidad razonable de estos estados condicionales ternarios y me pregunto si hay una forma de referirme al objeto que se evalúa en la condición para poder usarlo en la expresión. Algo como esto, quizás:

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

¿Algo como esto existe? Sé que puedo crear una variable para mantener el valor, pero sería bueno mantener todo dentro de una pequeña declaración apretada en las páginas de vista.

Gracias!

Respuesta

2

No, no hay una forma de hacer exactamente lo que estás pidiendo, sin crear una variable o duplicar a sí mismo, aunque se puede hacer algo como esto:

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

Esto supone que una nueva MailingAddress tendrá su propiedad de la ciudad/campo nulo por defecto.

La última coalescencia nula se puede quitar si la creación de una nueva dirección de correo inicializa el campo/propiedad de la ciudad para vaciar la cadena.

Pero esto no es realmente más corto, y es más hackish (en mi opinión), y casi con certeza menos rendimiento.

+2

+1 No porque yo use eso, pero me gusta cómo usa el encadenamiento :-) –

+2

No creo que esto realmente funcione para hacer lo que el OP quiere. Si Customer.MailingAddress no es nulo, entonces el resultado de la declaración es el objeto Customer.MailingAddress, pero el usuario quiere la propiedad de la Ciudad de ese objeto, no el objeto en sí. –

+1

@ Adam Porad. Eso no es cierto. El resultado ** del primer Bloque Paren ** es siempre una dirección de correo no referenciable. A continuación, obtenemos la propiedad/campo de esa dirección de correo (y null lo combinan si es necesario). – McKay

2

Puede usar el operador ?? para realizar comparaciones con nulo.

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

Por encima se puede reescribir de la siguiente manera:

Customer.MailingAddress ?? ""; 

En su caso Por lo general crear método de extensión:

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

    return null; 
} 

y su uso sería como esto:

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

El operador nulo coalescente no sería práctico aquí. –

+0

Respuesta actualizada. –

+0

Todo el debido respeto por una solución innovadora, pero eso es una gran cantidad de sobrecarga (y sintaxis arcana) para evitar la repetición de un nombre de tipo en un operador condicional ... –

2

¿Por qué no crear una propiedad en el objeto Cliente que contiene esa condición y simplemente llamarla directamente? es decir,

Customer.FormattedMailingAddress 

me gustaría escribir el código, pero estoy en mi móvil, sólo se necesitaría para poner la misma condición dentro de la get{} sin embargo.

+0

Estoy de acuerdo en que este es un enfoque agradable, me preguntaba si lo que estaba preguntando era posible o no, por ejemplo, donde no quisiera agregar una propiedad adicional. –

+0

Para mi proyecto (.net4 y mvc2) seguimos el patrón que describimos y hacemos todo esto (mostrar el formato de cadena) en los objetos mismos. Me gusta poder llamar una propiedad desde una vista y no preocuparme por ninguna lógica innecesaria (en absoluto) en las vistas mismas. Sin embargo, es una cuestión de gusto, y espero que mi sugerencia ayude al menos. – Dave

+0

También debería decir, que cuando una propiedad se usa en vistas múltiples, conserva el mismo 'formateo' (es decir, en una página desarrollada en un año, no usa lógica diferente, produciendo una cadena diferente, para el mismo campo, a menos que sea deliberado :)) – Dave

1

Acepto con @Dave, cree una extensión para su clase de Cliente.

Algo como esto:

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

A continuación, puede llamar a su método como este:

myCustomer.DisplayCity(); 

(nota: las extensiones no se pueden crear como una propiedad, por lo que este tendría que ser una método.ver Does C# have extension properties? para más detalles)

1

Se puede crear un método de extensión para obtener el valor o devolver una cadena vacía:

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

     return ""; 
    } 

luego llamarlo:

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

Esto funcionaría para cualquier objeto .

Cuestiones relacionadas