ฉันอ่านข้อกำหนดภาษา 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
และเป็นy
null
แต่การประเมินผลสำหรับ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?
ไม่เกี่ยวข้อง (แน่นอนว่านี่ไม่ใช่คำตอบที่สมบูรณ์มีเพียงเชื้อเดียวเท่านั้น)