terça-feira, 7 de junho de 2022

C#: Valores Nulos e Operadores Relacionados (??, ??=, ?. e ?[])

Depois de alguns anos, voltando a trabalhar com C# e com isso, algumas novidades. Se tem uma coisa que senti saudade no C# que o Java não tinha são o operador de coalescência nula e o operador de condicional nulos (também conhecido como Operador Elvis, porque parece um emoticon do Elvis Presley), muito útil para evitar o tal famoso NullPointerException. Mas vamos por partes:

Operador de coalescência nula (?? e ??=)

Mas o que faz este operador? Suponha que temos uma variável de um objeto que não sabemos se ele está nulo ou alocado, mas que se tiver nulo, queremos usar um valor padrão, provavelmente teríamos um código assim:

1. int default = 5;
2. int? num = busqueUmNumeroOuNulo();
3. if(num==null){
4.    num=default;
5. }

mas com este operador, podemos reduzir essas o algoritmo desta maneira:

1. int default = 5;
2. int ? num = busqueUmNumeroOuNulo()??default;

O que fiz? estou dizendo que o num receberá o retorno da função busqueUmNumeroOuNulo(), mas que se ela retornar null, ele deverá receber o valor de default.

E assim como a maioria dos operadores, ele também pode ser usado de forma autoatribuído. Para fins de comparação, o primeiro código ficaria assim.

1. int default = 5;
2. int ? num = busqueUmNumeroOuNulo();
3. num ??= default;

O operador ??= está indicando que se a variável num for null, atribua o valor de default para ele.

Só lembrando que o operador ?? está disponível no C# a partir da versão 7.3 e o operador ??= a partir da versão 8.0.

Operador condicionais nulos (?. e ?[])

Os operadores condicionais nulos são operadores que podemos usar ao acessar um atributo ou método de algum objeto sem ter medo de um NullPointerException. Vamos pegar um código de exemplo:

1. Object obj = ObjetoA.AtributoB.MetodoC();

Nesta linha de código fictícia, estou acessando de um objeto, um atributo e deste atributo, eu executo um método. O problema desta linha é que o ObjetoA pode ser nulo e não tenho garantia de que está alocado ou não. Como resolvo o problema? Tradicionalmente faríamos assim:

1. Object obj = null ;
2. if (ObjetoA!= null ){
3.     obj = ObjetoA.AtributoB.MetodoC();
4.}

Entretanto, com o operador condicional nulo, podemos reduzir da seguinte forma:

1. Object obj = ObjetoA?.AtributoB.MetodoC();

Com isso, se o ObjetoA for nulo, ele não tentará acessar o AtributoB e muito menos tentar executar o MetodoC, e retornará null direto. Note que se AtributoB puder ser null, teríamos que fazer outra checagem, mas com o operador ?. podemos simplesmente adicionar na linha dessa forma:

1. Object obj = ObjetoA?.AtributoB?.MetodoC();

Assim garantimos que poderemos acessar tudo ou nada sem se preocupar com NullPointerException.

Vale a pena notar também que o mesmo operador funciona com Arrays, então podemos tentar acessar um array desta forma

1. valor = array?[0]

Neste caso, se a variável array não for null, eu acesso normalmente o valor que está na posição 0, se for nulo, simplemente retorna null.

Nenhum comentário:

Postar um comentário