C# 11 -  Melhorias no uso de nameof


  Hoje veremos o novo recurso do C# 11 :  extensão dos recursos da expressão nameof

Uma expressão nameof produz o nome de uma variável, tipo ou membro como a constante de string.

Exemplos de uso da expressão nameof :


Console.WriteLine(nameof(System.Collections.Generic));       // Generic
Console.WriteLine(nameof(List<int>));                               // List
Console.WriteLine(nameof(List<int>.Count));                      // Count
Console.WriteLine(nameof(List<int>.Add));                         // Add

var numeros = new List<int> { 1, 2, 3 };

Console.WriteLine(nameof(numeros));                                // numbers
Console.WriteLine(nameof(numeros.Count));                       // Count
Console.WriteLine(nameof(numeros.Add));                         // Add
 

Como podemos observar no caso de um tipo e de um namespace, o nome produzido não é totalmente qualificado.

No caso de identificadores literais, o caractere @ não faz parte de um nome, como mostra o exemplo a seguir:


var @novo = 5;
Console.WriteLine(nameof(@novo));    // novo
 

Uma expressão nameof é avaliada em tempo de compilação e não tem efeito em tempo de execução.

Você pode usar uma expressão nameof para tornar o código de verificação de argumentos mais fácil de manter. Exemplo:

public string Nome
{
    get => nome;
    set => nome = value ?? throw new ArgumentNullException(nameof(value), $"{nameof(Nome)} não pode ser null");
}

Com o C# 11 é possível especificar o nome de qualquer parâmetro de método em um atributo da declaração do método usando os operadores nameof.

Isso ocorre porque quando os nomes dos parâmetros e os nomes de parâmetro de tipo são usados em uma expressão nameof, eles sempre estão no escopo.

Isso torna possível adicionar facilmente atributos para analisar se temos um nullabe.

O exemplo a seguir mostra como fazer isso para:

  1. Um atributo em um método;
  2. Uma função local;
  3. E o parâmetro de uma expressão lambda;
[ParameterString(nameof(msg))]
public static void Metodo(string msg)
{
    [ParameterString(nameof(T))]
    void FuncaoLocal<T>(T param) { }

    var expressao = ([ParameterString(nameof(aNumero))] int aNumero) => aNumero.ToString();
}

Assim podemos agora especificar o nome de um parâmetro de método em um atributo na declaração do parâmetro ou método e podemos usar este recurso adicionando atributos para análise de código. Exemplo:

using System;

public class MeuAtributo : Attribute
{
    private readonly string _nomeParametro;

    public MeuAtributo(string nomeParametro)
    {
        _nomeParametro = nomeParametro;
    }
}

public class MinhaClasse
{
    [MeuAtributo(nameof(param))]
    public void Metodo(int param, [MeuAtributo(nameof(param))] int outroParametro)
    {
        Console.WriteLine("C# 11 - Usando nameof");
    }
}

E estamos conversados...

"Dando graças ao Pai que nos fez idôneos para participar da herança dos santos na luz;
O qual nos tirou da potestade das trevas, e nos transportou para o reino do Filho do seu amor;"
Colossenses 1:12,13

Referências:


José Carlos Macoratti