ใน C # 6 คุณสามารถใช้ตัวnameof()ดำเนินการเพื่อรับสตริงที่มีชื่อของตัวแปรหรือประเภท
สิ่งนี้ได้รับการประเมินในเวลาคอมไพล์หรือรันไทม์ผ่าน Roslyn API บางตัว?
ใน C # 6 คุณสามารถใช้ตัวnameof()ดำเนินการเพื่อรับสตริงที่มีชื่อของตัวแปรหรือประเภท
สิ่งนี้ได้รับการประเมินในเวลาคอมไพล์หรือรันไทม์ผ่าน Roslyn API บางตัว?
คำตอบ:
ใช่. nameof()ได้รับการประเมินตามเวลาคอมไพล์ ดูข้อมูลจำเพาะเวอร์ชันล่าสุด:
นิพจน์ nameof เป็นค่าคงที่ ในทุกกรณี nameof (... ) จะถูกประเมินในเวลาคอมไพล์เพื่อสร้างสตริง อาร์กิวเมนต์ของมันไม่ได้รับการประเมินที่รันไทม์และถือว่าเป็นโค้ดที่ไม่สามารถเข้าถึงได้ (อย่างไรก็ตามจะไม่แสดงคำเตือน "โค้ดที่ไม่สามารถเข้าถึงได้")
คุณจะเห็นได้จากตัวอย่าง TryRoslynที่สิ่งนี้:
public class Foo
{
    public void Bar()
    {
        Console.WriteLine(nameof(Foo));
    }
}
รวบรวมและถอดรหัสเป็นสิ่งนี้:
public class Foo
{
    public void Bar()
    {
        Console.WriteLine("Foo");
    }
}
เทียบเท่ากับเวลาทำงานคือ:
public class Foo
{
    public void Bar()
    {
        Console.WriteLine(typeof(Foo).Name);
    }
}
ดังที่ได้กล่าวไว้ในความคิดเห็นนั่นหมายความว่าเมื่อคุณใช้nameofกับพารามิเตอร์ประเภทในประเภททั่วไปอย่าคาดหวังว่าจะได้รับชื่อของประเภทไดนามิกจริงที่ใช้เป็นพารามิเตอร์ประเภทแทนที่จะเป็นเพียงชื่อพารามิเตอร์ประเภท ดังนั้นสิ่งนี้:
public class Foo
{
    public void Bar<T>()
    {
        Console.WriteLine(nameof(T));
    }
}
จะกลายเป็นสิ่งนี้:
public class Foo
{
    public void Bar<T>()
    {
        Console.WriteLine("T");
    }
}
              ฉันต้องการเพิ่มคำตอบที่ได้รับจาก @ I3arnonด้วยหลักฐานที่ได้รับการประเมินในเวลาคอมไพล์
สมมติว่าฉันต้องการพิมพ์ชื่อของตัวแปรในคอนโซลโดยใช้ตัวnameofดำเนินการ:
 var firstname = "Gigi";
 var varname = nameof(firstname);
 Console.WriteLine(varname); // Prints "firstname" to the console
เมื่อคุณตรวจสอบ MSIL ที่สร้างขึ้นคุณจะเห็นว่ามันเทียบเท่ากับการประกาศสตริงเนื่องจากการอ้างอิงอ็อบเจ็กต์ไปยังสตริงถูกผลักไปที่สแต็กโดยใช้ตัวldstrดำเนินการ:
IL_0001: ldstr "Gigi"
IL_0006: stloc.0
IL_0007: ldstr "firstname"
IL_000c: stloc.1
IL_000d: ldloc.1
IL_000e: call void [mscorlib]System.Console::WriteLine(string)
คุณจะสังเกตเห็นว่าการประกาศสตริงชื่อแรกและการใช้ตัวnameofดำเนินการสร้างรหัสเดียวกันใน MSIL ซึ่งหมายความnameofว่ามีประสิทธิภาพเทียบเท่ากับการประกาศตัวแปรสตริง
nameofดำเนินการไม่ใช่สตริงฮาร์ดโค้ดธรรมดา