Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

18 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
martes, 2 de octubre de 2018
¿Qué podría salir mal? Pues como uno que os habla, seguro que muchos de vosotros habéis comparado miles de veces si un objeto es nulo utilizando un patrón de código C# como el siguiente:
var invoice = _invoiceRepository.GetById(18);
if(invoice == null) 
{
    // Hacer algo
}
¿Qué podría salir mal, verdad?

Pues aunque pueda parecer raro, hay casos en los que la comparación anterior no funcionaría bien... o mejor dicho, no funcionaría como esperamos.

Hace unos días leía un post de Khalid Abuhakmeh en el que hacía referencia a una charla de Channel 9 en la que Mads Torgersen recomendaba no utilizar la doble igualdad para comparar con null (minuto 33:00, aprox.)

En su lugar, la recomendación del lead designer del lenguaje C# en Microsoft es utilizar la expresión is null, como en el siguiente ejemplo:
var invoice = _invoiceRepository.GetById(18);
if(invoice is null) 
{
    // Hacer algo
}

Ahí queda eso :)

El motivo: la sobrecarga de operadores

¿Y cuál es la causa de esta recomendación? Pues básicamente, que no siempre podemos estar seguros del resultado de esta operación. Como recordaréis, muchos de los operadores de C# pueden ser sobrecargados, y la comparación de igualdad == no es una excepción.

Si por algún motivo se sobrescribiera dicho operador y su lógica introducida así lo decidiera, podríamos encontrarnos con un resultado poco previsible y, sobre todo, muy difícil de depurar.

Es decir, imaginemos que un descerebrado desarrollador introduce un código como el siguiente en la clase Invoice:
public class Invoice
{
    public int Id { get; set; }
    [...]

    public static bool operator == (Invoice a, Invoice b)
    {
        if(a is null || b is null)
        {
            return true;
        }
        return a.Id == b.Id;
    }
}
Como veis, estamos indicando que el operador de igualdad retornará cierto si alguno de los operandos son nulos, por lo que el siguiente resultado será algo diferente a lo que podríamos esperar:
var invoice = new Invoice {  Id = 1 };
Console.WriteLine(invoice == null);      // --> True
Console.WriteLine(invoice is null);      // --> False
En cambio, dado que el operador is no es sobrecargable, el resultado será siempre el esperado.

En fin, la verdad es que son escenarios muy raros de encontrar, pero está bien saber que esta posibilidad existe. Por mi parte no creo que me pueda acostumbrar fácilmente a utilizar is en lugar de == y tampoco tengo claro que me valga la pena el esfuerzo, pero, sin duda, sería lo más correcto.

Publicado en Variable not found.

3 Comentarios:

Anónimo dijo...

Sobrecargar el == debería considerarse acto de terrorismo

José María Aguilar dijo...

Sin duda ;DD

Kike dijo...

Como ya sabemos todos, los terrorístias existen: posiblemente en forma de becarios motivados (sin faltar, todos hemos pasado por ahí, solo hace falta enseñar a la próxima generación).

Peronsalmente voy a darle un chance a esta metodología cuando aplique. Es un caso que normalmente pasamos tres kilos de tener en cuenta porque seguramente, de ocurrir, sería porque el software ya está en manos de otro equipo y tú trabajando en otra empresa o preferiblemente jubilado (já). Y claro, "que se jodan los que vengan" es cómodo, pero es una variación del "que se joda mi yo del futuro, que el ya lo solucionará".

Señor presente aboga por programar como si el "pull" tóxico decódigo te lo fueras a tragar tú mismo. Y si la mayoría lo intentara día a día todos seríamos más felices.