Lo siento por este ejemplo incómodo, pero quiero mantenerlo lo más directo posible.
Digamos que analicé un archivo json, lo que me da la jerarquía a continuación
var customers = myObj.SubObj?.CustomerList.EmptyIfNull(); var plusCustomers = customers.Where(...) // Resharper warningmyobj no puede ser nulo SubObject puede ser nulo a veces
Tengo un método de extensión
IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> enumerable) => enumerable ?? Enumerable.Empty<T>();Así que espero que la línea plusCustomers sea segura (lista vacía en lugar de nula). Pero recibo una advertencia
posible asignación "nula" a una entidad no anulable
Si reemplazo la primera línea con
var customers = myObj.SubObj.CustomerList.EmptyIfNull();Me deshago de la advertencia, pero eso no es correcto. ¿Cómo puedo convencer a Resharper de que esto está bien?... o me equivoco?
Puede agregar paréntesis:
(myObj.SubObj?.CustomerList).EmptyIfNull(); El efecto del encadenamiento nulo ( ?. ) es evaluar toda la cadena de accesos de miembros a nulo, si el operando LHS es nulo, en lugar de evaluar solo ese acceso de miembro único a nulo. Por ejemplo, considere una larga cadena de accesos de miembros abcdef . Si solo a es anulable, solo necesitaría escribir ? después de a para que esto sea seguro. No solo evalúa a?.b como nulo si a es nulo, porque en ese caso tendría que escribir ? después de cada acceso de miembro para que esto sea seguro, y eso es un poco molesto.
Entonces, sin los corchetes, todo el acceso del miembro se anula debido a ?. , independientemente de cómo se llame al final.
Al agregar corchetes, rompe la cadena de accesos de los miembros, de modo que myObj.SubObj?.CustomerList sea de un tipo anulable, y llamar a EmptyIfNull en eso funciona como se esperaba, devolviendo cualquier tipo que EmptyIfNull deba devolver.