nameof (C#-Referenz)

Wird verwendet, um den einfachen (nicht qualifizierten) Zeichenfolgennamen einer Variablen, eines Typs oder eines Members abzurufen.

Beim Melden von Fehlern im Code, Einbinden von MVC-Links (Model-View-Controller) und Auslösen von durch Eigenschaften geänderten Ereignissen usw. ist es oft erforderlich, den Zeichenfolgennamen einer Methode zu erfassen. Mithilfe von nameof bleibt der Code beim Umbenennen von Definitionen gültig. Bisher mussten zum Verweisen auf Definitionen Zeichenfolgenliterale verwendet werden; dies ist jedoch fehleranfällig, wenn Codeelemente umbenannt werden, da Tools diese Zeichenfolgenliterale nicht überprüfen können.

Ein nameof-Ausdruck hat die folgende Form:

if (x == null) throw new ArgumentNullException(nameof(x));  
WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode"  

Wichtige Einsatzbeispiele

Diese Beispiele zeigen die wichtigsten Anwendungsfälle für nameof.

Überprüfen von Parametern:

void f(string s) {  
   if (s == null) throw new ArgumentNullException(nameof(s));  
}  

MVC-Aktionslinks:

<%= Html.ActionLink("Sign up",  
            @typeof(UserController),  
            @nameof(UserController.SignUp))  
%>  

INotifyPropertyChanged:

int p {  
   get { return this.p; }  
   set { this.p = value; PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.p)); } // nameof(p) works too  
}  

XAML-Abhängigkeitseigenschaft:

public static DependencyProperty AgeProperty = DependencyProperty.Register(nameof(Age), typeof(int), typeof(C));  

Protokollieren:

void f(int i) {  
   Log(nameof(f), "method entry");  
}  

Attribute:

[DebuggerDisplay("={" + nameof(GetString) + "()}")]  
class C {  
   string GetString() { }  
}  

Beispiele

Einige C#-Beispiele:

using Stuff = Some.Cool.Functionality  
class C {  
    static int Method1 (string x, int y) {}  
    static int Method1 (string x, string y) {}  
    int Method2 (int z) {}  
    string f<T>() => nameof(T);  
}  

var c = new C()  

nameof(C) -> "C"  
nameof(C.Method1) -> "Method1"   
nameof(C.Method2) -> "Method2"  
nameof(c.Method1) -> "Method1"   
nameof(c.Method2) -> "Method2"  
nameof(z) -> "z" // inside of Method2 ok, inside Method1 is a compiler error  
nameof(Stuff) = "Stuff"  
nameof(T) -> "T" // works inside of method but not in attributes on the method  
nameof(f) -> "f"  
nameof(f<T>) -> syntax error  
nameof(f<>) -> syntax error  
nameof(Method2()) -> error "This expression does not have a name"  

Hinweise

Das Argument für nameof muss ein einfacher Name, qualifizierter Name, Memberzugriff, Basiszugriff mit angegebenem Member oder dieser Zugriff mit angegebenem Member sein. Der Argumentausdruck identifiziert eine Codedefinition, wird jedoch niemals ausgewertet.

Da das Argument syntaktisch ein Ausdruck sein muss, ist vieles unzulässig; eine Auflistung wäre jedoch nicht sinnvoll. Fehler werden bspw. erzeugt durch: vordefinierte Typen (z. B. int oder void), auf NULL festlegbare Typen (Point?), Arraytypen (Customer[,]), Zeigertypen (Buffer*), qualifizierte Aliase (A::B), ungebundene generische Typen (Dictionary<,>), Vorverarbeitungssymbole (DEBUG) und Bezeichnungen (loop:).

Wenn Sie den vollqualifizierten Namen abrufen müssen, können Sie den typeof-Ausdruck zusammen mit nameof verwenden. Zum Beispiel:

class C {
    void f(int i) {  
        Log($"{typeof(C)}.{nameof(f)}", "method entry");  
    }
}

Leider ist typeof kein konstanter Ausdruck wie nameof, sodass typeof nicht zusammen mit nameof an den gleichen Orten wie nameof verwendet werden kann. Beispielsweise würde Folgendes einen Kompilierungsfehler CS0182 erzeugen:

[DebuggerDisplay("={" + typeof(C) + nameof(GetString) + "()}")]  
class C {  
   string GetString() { }  
}  

In den Beispielen sehen Sie, dass Sie einen Typnamen verwenden und auf den Namen einer Instanzmethode zugreifen können. Sie müssen nicht über eine Instanz des Typs verfügen, wie es in ausgewerteten Ausdrücken erforderlich ist. Die Verwendung des Typnamens kann in einigen Situationen sehr praktisch sein, und da Sie nur auf den Namen verweisen und keine Instanzdaten verwenden, müssen Sie keine Instanzvariable und keinen Ausdruck erfinden.

Sie können auf die Member einer Klasse in Attributausdrücken in der Klasse verweisen.

Es gibt keine Möglichkeit, Signaturinformationen wie z. B. „Method1 (str, str)“ abzurufen. Dazu müssen Sie z. B. einen Ausdruck (Expression e = () => A.B.Method1("s1", "s2")) verwenden und die MemberInfo aus der resultierenden Ausdrucksbaumstruktur abrufen.

Sprachspezifikationen

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.

Siehe auch

C#-Referenz
C#-Programmierhandbuch
typeof