ฉันอ่านข้อกำหนดภาษา C # บนตัวดำเนินการตรรกะแบบมีเงื่อนไข ||และ&&หรือที่เรียกว่าตัวดำเนินการทางตรรกะที่ลัดวงจร สำหรับฉันแล้วมันดูเหมือนไม่ชัดเจนว่าสิ่งเหล่านี้มีอยู่สำหรับบูลีนที่เป็นโมฆะหรือไม่เช่นประเภทตัวถูกดำเนินการNullable<bool>(เขียนด้วยbool?) ดังนั้นฉันจึงลองด้วยการพิมพ์แบบไม่ไดนามิก:
bool a = true;
bool? b = null;
bool? xxxx = b || a; // compile-time error, || can't be applied to these types
ดูเหมือนจะช่วยชำระคำถามได้ (ฉันไม่เข้าใจข้อกำหนดอย่างชัดเจน แต่สมมติว่าการใช้งานคอมไพเลอร์ Visual C # ถูกต้องตอนนี้ฉันรู้แล้ว)
อย่างไรก็ตามฉันก็อยากลองdynamicผูกด้วยเช่นกัน ดังนั้นฉันจึงลองสิ่งนี้แทน:
static class Program
{
static dynamic A
{
get
{
Console.WriteLine("'A' evaluated");
return true;
}
}
static dynamic B
{
get
{
Console.WriteLine("'B' evaluated");
return null;
}
}
static void Main()
{
dynamic x = A | B;
Console.WriteLine((object)x);
dynamic y = A & B;
Console.WriteLine((object)y);
dynamic xx = A || B;
Console.WriteLine((object)xx);
dynamic yy = A && B;
Console.WriteLine((object)yy);
}
}
ผลลัพธ์ที่น่าประหลาดใจคือการดำเนินการนี้โดยไม่มีข้อยกเว้น
ดีxและyจะไม่น่าแปลกใจที่การประกาศของพวกเขานำไปสู่คุณสมบัติทั้งสองถูกดึงและค่านิยมที่เกิดขึ้นเป็นไปตามคาดxเป็นtrueและเป็นynull
แต่การประเมินผลสำหรับxxของA || Bนำไปสู่การไม่มีข้อยกเว้นเวลาที่มีผลผูกพันและมีเพียงทรัพย์สินที่ได้อ่านไม่ได้A Bทำไมสิ่งนี้ถึงเกิดขึ้น? อย่างที่คุณบอกเราสามารถเปลี่ยนผู้เริ่มต้นBให้ส่งคืนวัตถุที่บ้าคลั่งเช่น"Hello world"และxxจะยังคงประเมินtrueโดยไม่มีปัญหาการผูกมัด ...
การประเมินA && B(สำหรับyy) ยังทำให้ไม่มีข้อผิดพลาดเวลาผูกมัด และที่นี่คุณสมบัติทั้งสองจะถูกดึงออกมาแน่นอน เหตุใดสิ่งนี้จึงได้รับอนุญาตจากตัวประสานรันไทม์ ถ้าวัตถุที่ส่งคืนจากBเปลี่ยนเป็นวัตถุ "ไม่ดี" (เช่น a string) จะมีข้อยกเว้นการผูก
พฤติกรรมนี้ถูกต้องหรือไม่? (คุณจะสรุปได้อย่างไรว่าจากข้อมูลจำเพาะ?)
ถ้าคุณพยายามBเป็นตัวถูกดำเนินการครั้งแรกที่ทั้งสองB || AและB && Aให้ยกเว้นรันไทม์เครื่องผูก ( B | AและB & Aปรับการทำงานทุกอย่างเป็นเรื่องปกติที่ไม่ใช่ลัดวงจรผู้ประกอบการ|และ&)
(พยายามกับคอมไพเลอร์ C # ของ Visual Studio 2013 และเวอร์ชันรันไทม์. NET 4.5.2)
Nullable<Boolean>เกี่ยวข้องเลยมีเพียงบูลีนชนิดบรรจุกล่องเท่านั้นที่ถือว่าเป็นdynamic- การทดสอบของคุณbool?ไม่เกี่ยวข้อง (แน่นอนว่านี่ไม่ใช่คำตอบที่สมบูรณ์มีเพียงเชื้อเดียวเท่านั้น)