nameof (C#-Referenz)nameof (C# Reference)

Wird verwendet, um den einfachen (nicht qualifizierten) Zeichenfolgennamen einer Variablen, eines Typs oder eines Members abzurufen.Used to obtain the simple (unqualified) string name of a variable, type, or member.

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.When reporting errors in code, hooking up model-view-controller (MVC) links, firing property changed events, etc., you often want to capture the string name of a method. Mithilfe von nameof bleibt der Code beim Umbenennen von Definitionen gültig.Using nameof helps keep your code valid when renaming definitions. 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.Before, you had to use string literals to refer to definitions, which is brittle when renaming code elements because tools do not know to check these string literals.

Ein nameof-Ausdruck hat die folgende Form:A nameof expression has this form:

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

Wichtige EinsatzbeispieleKey Use Cases

Diese Beispiele zeigen die wichtigsten Anwendungsfälle für nameof.These examples show the key use cases for nameof.

Überprüfen von Parametern:Validate parameters:

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

MVC-Aktionslinks:MVC Action links:

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

INotifyPropertyChanged: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:XAML dependency property:

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

Protokollieren:Logging:

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

Attribute:Attributes:

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

BeispieleExamples

Einige C#-Beispiele:Some C# examples:

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()  

class Test {  
    static void Main (string[] args) {  
        Console.WriteLine(nameof(C)); // -> "C"  
        Console.WriteLine(nameof(C.Method1)); // -> "Method1"   
        Console.WriteLine(nameof(C.Method2)); // -> "Method2"  
        Console.WriteLine(nameof(c.Method1)); // -> "Method1"   
        Console.WriteLine(nameof(c.Method2)); // -> "Method2"  
        // Console.WriteLine(nameof(z)); -> "z" [inside of Method2 ok, inside Method1 is a compiler error]  
        Console.WriteLine(nameof(Stuff)); // -> "Stuff"  
        // Console.WriteLine(nameof(T)); -> "T" [works inside of method but not in attributes on the method]  
        Console.WriteLine(nameof(f)); // -> "f"  
        // Console.WriteLine(nameof(f<T>)); -> [syntax error]  
        // Console.WriteLine(nameof(f<>)); -> [syntax error]  
        // Console.WriteLine(nameof(Method2())); -> [error "This expression does not have a name"]  
    }
}

HinweiseRemarks

Das Argument für nameof muss ein einfacher Name, qualifizierter Name, Memberzugriff, Basiszugriff mit angegebenem Member oder dieser Zugriff mit angegebenem Member sein.The argument to nameof must be a simple name, qualified name, member access, base access with a specified member, or this access with a specified member. Der Argumentausdruck identifiziert eine Codedefinition, wird jedoch niemals ausgewertet.The argument expression identifies a code definition, but it is never evaluated.

Da das Argument syntaktisch ein Ausdruck sein muss, ist vieles unzulässig; eine Auflistung wäre jedoch nicht sinnvoll.Because the argument needs to be an expression syntactically, there are many things disallowed that are not useful to list. 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:).The following are worth mentioning that produce errors: predefined types (for example, int or void), nullable types (Point?), array types (Customer[,]), pointer types (Buffer*), qualified alias (A::B), and unbound generic types (Dictionary<,>), preprocessing symbols (DEBUG), and labels (loop:).

Wenn Sie den vollqualifizierten Namen abrufen müssen, können Sie den typeof-Ausdruck zusammen mit nameof verwenden.If you need to get the fully-qualified name, you can use the typeof expression along with nameof. Zum Beispiel:For example:

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.Unfortunately typeof is not a constant expression like nameof, so typeof cannot be used in conjunction with nameof in all the same places as nameof. Beispielsweise würde Folgendes einen Kompilierungsfehler CS0182 erzeugen:For example, the following would cause a CS0182 compile error:

[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.In the examples you see that you can use a type name and access an instance method name. Sie müssen nicht über eine Instanz des Typs verfügen, wie es in ausgewerteten Ausdrücken erforderlich ist.You do not need to have an instance of the type, as required in evaluated expressions. 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.Using the type name can be very convenient in some situations, and since you are just referring to the name and not using instance data, you do not need to contrive an instance variable or expression.

Sie können auf die Member einer Klasse in Attributausdrücken in der Klasse verweisen.You can reference the members of a class in attribute expressions on the class.

Es gibt keine Möglichkeit, Signaturinformationen wie z. B. „Method1 (str, str)“ abzurufen.There is no way to get a signatures information such as "Method1 (str, str)". Dazu müssen Sie z. B. einen Ausdruck (Expression e = () => A.B.Method1("s1", "s2")) verwenden und die MemberInfo aus der resultierenden Ausdrucksbaumstruktur abrufen.One way to do that is to use an Expression, Expression e = () => A.B.Method1("s1", "s2"), and pull the MemberInfo from the resulting expression tree.

SprachspezifikationenLanguage Specifications

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation.For more information, see the C# Language Specification. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.The language specification is the definitive source for C# syntax and usage.

Siehe auchSee Also