ใน 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
ดำเนินการไม่ใช่สตริงฮาร์ดโค้ดธรรมดา