C# Language Nome dell'operatore

Esempio

L'operatore nameof restituisce il nome di un elemento di codice come una string . Ciò è utile quando si INotifyPropertyChanged eccezioni relative agli argomenti del metodo e anche quando si implementa INotifyPropertyChanged .

public string SayHello(string greeted)
{
    if (greeted == null)
        throw new ArgumentNullException(nameof(greeted));
    
    Console.WriteLine("Hello, " + greeted);
}

L'operatore nameof viene valutato al momento della compilazione e modifica l'espressione in una stringa letterale. Questo è utile anche per le stringhe che prendono il nome dal loro membro che le espone. Considera quanto segue:

public static class Strings
{
    public const string Foo = nameof(Foo); // Rather than Foo = "Foo"
    public const string Bar = nameof(Bar); // Rather than Bar = "Bar"
}

Dal nameof espressioni nameof sono costanti in fase di compilazione, possono essere utilizzate in attributi, etichette case , istruzioni switch e così via.


È conveniente usare nameof con Enum s. Invece di:

Console.WriteLine(Enum.One.ToString());

è possibile usare:

Console.WriteLine(nameof(Enum.One))

L'output sarà One in entrambi i casi.


L'operatore nameof può accedere ai membri non statici usando la sintassi di tipo statico. Invece di fare:

string foo = "Foo";
string lengthName = nameof(foo.Length);

Può essere sostituito con:

string lengthName = nameof(string.Length);

L'output sarà Length in entrambi gli esempi. Tuttavia, quest'ultimo impedisce la creazione di istanze non necessarie.


Sebbene l'operatore nameof con la maggior parte dei costrutti di linguaggio, esistono alcune limitazioni. Ad esempio, non è possibile utilizzare l'operatore nameof tipi generici aperti o valori restituiti dal metodo:

public static int Main()
{   
    Console.WriteLine(nameof(List<>)); // Compile-time error
    Console.WriteLine(nameof(Main())); // Compile-time error
}

Inoltre, se lo si applica a un tipo generico, il parametro di tipo generico verrà ignorato:

Console.WriteLine(nameof(List<int>));  // "List"
Console.WriteLine(nameof(List<bool>)); // "List"

Per ulteriori esempi, vedere questo argomento dedicato a nameof .


Soluzione alternativa per le versioni precedenti ( maggiori dettagli )

Sebbene l'operatore nameof non esista in C # per le versioni precedenti alla 6.0, è possibile utilizzare funzionalità simili utilizzando MemberExpression come nell'esempio seguente:

6.0

Espressione:

public static string NameOf<T>(Expression<Func<T>> propExp)
{
    var memberExpression = propExp.Body as MemberExpression;
    return memberExpression != null ? memberExpression.Member.Name : null;
}

public static string NameOf<TObj, T>(Expression<Func<TObj, T>> propExp)
{
    var memberExpression = propExp.Body as MemberExpression;
    return memberExpression != null ? memberExpression.Member.Name : null;
}

Uso:

string variableName = NameOf(() => variable);
string propertyName = NameOf((Foo o) => o.Bar);

Si noti che questo approccio determina la creazione di un albero di espressioni per ogni chiamata, quindi le prestazioni sono molto peggiori rispetto all'operatore nameof che viene valutato in fase di compilazione e che non ha sovraccarico in fase di esecuzione.