(สำหรับข้อมูลเกี่ยวกับตัวช่วยข้อยกเว้นใหม่ใน Visual Studio 2017 ดูส่วนท้ายของคำตอบนี้)
พิจารณารหัสนี้:
String s = null;
Console.WriteLine(s.Length);
สิ่งนี้จะทำให้NullReferenceExceptionเกิดบรรทัดที่สองและคุณต้องการทราบว่าเหตุใด. NET จึงไม่บอกคุณว่าสิ่งsนั้นเป็นโมฆะเมื่อเกิดข้อยกเว้น
เพื่อให้เข้าใจว่าเหตุใดคุณจึงไม่ได้รับข้อมูลนั้นคุณควรจำไว้ว่าไม่ใช่แหล่งข้อมูล C # ที่ดำเนินการ แต่เป็น IL:
IL_0001: ldnull
IL_0002: stloc.0 // วินาที
IL_0003: ldloc.0 // วินาที
IL_0004: callvirt System.String.get_Length
IL_0009: เรียก System.Console.WriteLine
เป็นcallvirtopcode ที่พ่นNullReferenceExceptionและทำเช่นนั้นเมื่ออาร์กิวเมนต์แรกบนสแต็กการประเมินเป็นการอ้างอิงที่ว่าง (อันที่โหลดโดยใช้ldloc.0)
หาก .NET ควรจะสามารถที่จะบอกว่ามันเป็นเรื่องที่เป็นโมฆะอ้างอิงที่ควรในบางติดตามวิธีการที่อาร์กิวเมนต์แรกในกองประเมินผลมารูปแบบs sในกรณีนี้มันง่ายที่เราจะเห็นว่ามันเป็นsโมฆะ แต่จะเกิดอะไรขึ้นถ้าค่านั้นเป็นค่าส่งคืนจากการเรียกฟังก์ชันอื่นและไม่ได้เก็บไว้ในตัวแปรใด ๆ อย่างไรก็ตามข้อมูลประเภทนี้ไม่ใช่สิ่งที่คุณต้องการติดตามในเครื่องเสมือนเช่นเครื่องเสมือน. NET
เพื่อหลีกเลี่ยงปัญหานี้ฉันขอแนะนำให้คุณทำการตรวจสอบอาร์กิวเมนต์ที่ว่างเปล่าในการเรียกวิธีสาธารณะทั้งหมด (เว้นแต่คุณจะอนุญาตการอ้างอิง null):
public void Foo(String s) {
if (s == null)
throw new ArgumentNullException("s");
Console.WriteLine(s.Length);
}
ถ้า null ถูกส่งไปยังเมธอดคุณจะได้รับข้อยกเว้นที่อธิบายได้อย่างชัดเจนว่าปัญหาคืออะไร (นั่นsคือโมฆะ)
สี่ปีต่อมา Visual Studio 2017 มีตัวช่วยข้อยกเว้นใหม่ที่จะพยายามบอกว่าอะไรเป็นโมฆะเมื่อมีการNullReferenceExceptionโยน มันยังสามารถให้ข้อมูลที่จำเป็นแก่คุณได้เมื่อเป็นค่าส่งคืนของเมธอดที่เป็นโมฆะ:

โปรดทราบว่าสิ่งนี้ใช้ได้เฉพาะในรุ่น DEBUG เท่านั้น