En C #, diga que desea extraer un valor de PropertyC en este ejemplo y ObjectA, PropertyA y PropertyB pueden ser todos nulos.
ObjectA.PropertyA.PropertyB.PropertyC
¿Cómo puedo obtener PropertyC de forma segura con la menor cantidad de código?
Ahora mismo comprobaría:
if(ObjectA != null && ObjectA.PropertyA !=null && ObjectA.PropertyA.PropertyB != null)
{
// safely pull off the value
int value = objectA.PropertyA.PropertyB.PropertyC;
}
Sería bueno hacer algo más como esto (pseudocódigo).
int value = ObjectA.PropertyA.PropertyB ? ObjectA.PropertyA.PropertyB : defaultVal;
Posiblemente colapsó aún más con un operador de fusión nula.
EDITAR Originalmente dije que mi segundo ejemplo era como js, pero lo cambié a psuedo-code ya que se señaló correctamente que no funcionaría en js.
ObjectA
oPropertyA
sean nulos.Respuestas:
En C # 6 puede usar el operador condicional nulo . Entonces la prueba original será:
fuente
value
igual a siPropertyC
es nulo? o siPropertyB
es nulo? ¿y siObject A
es nulo?null
. Empieza de izquierda a derecha. Sin el azúcar sintáctico, esto es equivalente a una serie de declaraciones if dondeif(propertyX == null) {value = null} else if (propertyY == null){ value = null} else if......
la última expresión eventual esif(propertyZ != null) { value = propertyZ }
Método de extensión corto:
Utilizando
Puede encontrar este método de extensión simple y mucho más en http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/
EDITAR:
Después de usarlo por un momento, creo que el nombre correcto para este método debería ser IfNotNull () en lugar del original With ().
fuente
¿Puedes agregar un método a tu clase? Si no es así, ¿ha pensado en utilizar métodos de extensión? Puede crear un método de extensión para su tipo de objeto llamado
GetPropC()
.Ejemplo:
Uso:
Por cierto, esto supone que está utilizando .NET 3 o superior.
fuente
La forma en que lo estás haciendo es correcta.
Usted podría utilizar un truco como el descrito aquí , usando expresiones LINQ:
Pero es mucho más lento que verificar manualmente cada propiedad ...
fuente
Refactorizar para observar la Ley de Deméter
fuente
Actualización 2014: C # 6 tiene un nuevo operador
?.
llamado 'navegación segura' o 'propagación nula'Lea http://blogs.msdn.com/b/jerrynixon/archive/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator.aspx para obtener más detalles
Esta ha sido durante mucho tiempo una solicitud muy popular https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c-?tracking_code=594c10a522f8e9bc987ee4a5e2c0b38d
fuente
Obviamente, está buscando la mónada anulable :
se convierte en
Esto devuelve
null
, si alguna de las propiedades que aceptan valores NULL es nula; de lo contrario, el valor deValue
.Métodos de extensión LINQ:
fuente
SelectMany
método de extensión es utilizado por lafrom ... in ... from ... in ...
sintaxis.Suponiendo que tiene valores vacíos de tipos, un enfoque sería este:
Soy un gran fan de C #, pero una cosa muy buena en el nuevo Java (¿1.7?) Es el.? operador:
fuente
Este código es "la menor cantidad de código", pero no la mejor práctica:
fuente
Cuando necesito encadenar llamadas como esa, confío en un método auxiliar que creé, TryGet ():
En su caso, lo usaría así:
fuente
Vi algo en el nuevo C # 6.0, esto es usando '?' en lugar de comprobar
por ejemplo en lugar de usar
simplemente usa
Espero que haya ayudado a alguien.
ACTUALIZAR:
Podrías hacer esto ahora
fuente
Podrías hacer esto:
O incluso mejor podría ser esto:
fuente
puedes usar la siguiente extensión y creo que es realmente buena:
Y se usa así:
fuente
Escribiría su propio método en el tipo de PropertyA (o un método de extensión si no es su tipo) usando un patrón similar al tipo Nullable.
fuente
Acabo de tropezar con esta publicación.
Hace algún tiempo hice una sugerencia en Visual Studio Connect acerca de agregar un nuevo
???
operador.http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4104392-add-as-an-recursive-null-reference-check-opera
Esto requeriría algo de trabajo por parte del equipo del marco, pero no es necesario modificar el lenguaje, solo hacer algo de magia del compilador. La idea era que el compilador debería cambiar este código (sintaxis no permitida atm)
en este código
Para comprobar nulo, esto podría verse así
fuente
Escribí un método que acepta un valor predeterminado, así es como se usa:
Aquí está el código:
fuente
No es posible.
ObjectA.PropertyA.PropertyB
fallará siObjectA
es nulo debido a la eliminación de referencias nulas, lo cual es un error.if(ObjectA != null && ObjectA.PropertyA
... funciona debido a un cortocircuito, es decirObjectA.PropertyA
, nunca se comprobará siObjectA
es asínull
.La primera forma que propongas es la mejor y la más clara con intención. En todo caso, podría intentar rediseñar sin tener que depender de tantos nulos.
fuente
Este enfoque es bastante sencillo una vez que superas el lambda gobbly-gook:
Con un uso que podría verse así:
fuente
El
??
(operador de fusión nula) significa que si el primer argumento esnull
, devuelve el segundo en su lugar.fuente