nameof (C# リファレンス)nameof (C# Reference)

変数、型、またはメンバーの単純な (修飾されていない) 文字列名を取得するのに使用します。Used to obtain the simple (unqualified) string name of a variable, type, or member.

コード内のエラーの報告、モデル ビュー コントローラー (MVC) リンクのフック、プロパティの変更されたイベントの起動などの際には、多くの場合、メソッドの文字列名をキャプチャします。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. nameof の使用は、定義の名前を変更するときに、コードを有効な状態に保つのに役立ちます。Using nameof helps keep your code valid when renaming definitions. 以前は、定義を参照するのに文字列リテラルを使用する必要がありました。ツールには、これらの文字列リテラルを検査する方法がわからないため、コード要素の名前変更の際には当てになりません。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.

nameof 式のフォームは次のとおりです。A nameof expression has this form:

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

主なユース ケースKey Use Cases

ここでは、nameof の主なユース ケースを示します。These examples show the key use cases for nameof.

パラメーターの確認:Validate parameters:

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

MVC アクション リンク: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 依存関係プロパティ:XAML dependency property:

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

ログ:Logging:

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

属性:Attributes:

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

使用例Examples

ここでは、C# の例をいくつか示します。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()  

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"  

コメントRemarks

nameof への引数は、簡易名、修飾名、メンバー アクセス、メンバーを指定した base アクセス、またはメンバーを指定した this アクセスでなければなりません。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. 引数の式はコード定義を識別しますが、評価されることはありません。The argument expression identifies a code definition, but it is never evaluated.

引数は構文上、式でなければならないため、許容されないものが多数あります。特に必要がないため、ここではこのようなものについて逐一取り上げていません。Because the argument needs to be an expression syntactically, there are many things disallowed that are not useful to list. 定義済みの型 (たとえば、int または void)、Null 許容型 (Point?)、配列型 (Customer[,])、ポインター型 (Buffer*)、修飾されたエイリアス (A::B)、バインドされていないジェネリック型 (Dictionary<,>)、プリプロセッサ シンボル (DEBUG)、およびラベル (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:).

完全修飾名を取得する必要がある場合は、nameof と共に typeof 式を使用できます。If you need to get the fully-qualified name, you can use the typeof expression along with nameof. 例:For example:

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

残念ながら、typeofnameof のような定数式ではないので、nameof が使われるすべての場所で nameof と組み合わせて typeof を使うことはできません。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. たとえば、次のコードでは CS0182 コンパイル エラーが発生します。For example, the following would cause a CS0182 compile error:

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

上記の例では、型名を使用でき、インスタンス メソッド名にアクセスできることが分かります。In the examples you see that you can use a type name and access an instance method name. 評価された式で必要とされるような、型のインスタンスは必要ありません。You do not need to have an instance of the type, as required in evaluated expressions. 型名の使用は状況によっては非常に便利です。型名では名前を参照しているだけでインスタンス データを使用してはいないため、インスタンス変数や式を考慮する必要はありません。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.

クラスの属性式内でクラスのメンバーを参照できます。You can reference the members of a class in attribute expressions on the class.

"Method1 (str, str)" などの署名情報を取得する方法はありません。There is no way to get a signatures information such as "Method1 (str, str)". そうする 1 つの方法は、Expression e = () => A.B.Method1("s1", "s2") という式を使用し、結果として得られる式ツリーから MemberInfo を取得することです。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.

言語仕様Language Specifications

詳細については、「C# 言語の仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

関連項目See Also

C# リファレンスC# Reference
C# プログラミング ガイドC# Programming Guide
typeoftypeof