C # - วิธีการยืนยัน () ทำอะไรได้บ้าง มันยังมีประโยชน์หรือไม่


156

ฉันกำลังดีบั๊กด้วยจุดพักและฉันตระหนักถึงการเรียกร้องยืนยันหรือไม่ ฉันคิดว่ามันเป็นเพียงสำหรับการทดสอบหน่วย มันทำอะไรได้มากกว่าเบรกพอยต์? เนื่องจากฉันสามารถเบรกพอยต์ทำไมฉันจึงควรใช้ Assert


9
โดยวิธีการถ้าคุณสนใจในกำลังอ้างคุณแน่นอนควรจะเจาะเข้าไปในสัญญารหัส
MasterMastic

สำเนาซ้ำซ้อนที่เป็นไปได้ของstackoverflow.com/questions/129120/…
Michael Freidgeim

คำตอบ:


200

ในการรวบรวมดีบักให้Assertใช้เงื่อนไขบูลีนเป็นพารามิเตอร์และแสดงไดอะล็อกข้อผิดพลาดหากเงื่อนไขเป็นเท็จ โปรแกรมดำเนินการโดยไม่หยุดชะงักหากเงื่อนไขเป็นจริง

หากคุณคอมไพล์ใน Release ทุกรายการDebug.Assertจะถูกปล่อยออกโดยอัตโนมัติ


12
ฉันจะได้รับพฤติกรรมเดียวกันของ Debug.Assert ในโหมด Release ได้อย่างไร
Hamish Grubijan

15
Trace.Assert สำหรับโหมดการเปิดตัวอ้างอิงชัด: msdn.microsoft.com/en-us/library/… msdn.microsoft.com/en-us/library/e63efys0.aspx
Tim Abell

8
@HamishGrubijan และทำไมคุณถึงต้องการDebug.Assertในโหมดการเปิดตัว?
Camilo Martin

25
IMO การละเว้นการยืนยันจากรหัสการวางจำหน่ายก็เหมือนกับการฝึกซ้อมเรือชูชีพในขณะที่จอดอยู่ที่ท่าเรือแล้วทิ้งเรือชูชีพไว้ด้านหลังเมื่อคุณแล่นเรือ :)
chrisd

113
Asserts ไม่ใช่เรือชูชีพ แต่เป็นระบบตรวจจับภูเขาน้ำแข็ง เนื่องจากผู้ใช้ไม่ได้ควบคุมเรือการยืนยันในรหัสการปล่อยเพียงบอกพวกเขาถึงวาระ มันไม่ปล่อยให้พวกเขาหลีกเลี่ยงภูเขาน้ำแข็ง
สเตฟาน

97

จากรหัสเสร็จสมบูรณ์

8 การป้องกันการเขียนโปรแกรม

8.2 การยืนยัน

การยืนยันเป็นรหัสที่ใช้ในระหว่างการพัฒนาซึ่งโดยปกติจะเป็นรูทีนหรือมาโครที่อนุญาตให้โปรแกรมตรวจสอบตัวเองขณะที่มันทำงาน เมื่อการยืนยันเป็นจริงนั่นหมายความว่าทุกอย่างทำงานตามที่คาดไว้ เมื่อเป็นเท็จนั่นหมายความว่าตรวจพบข้อผิดพลาดที่ไม่คาดคิดในรหัส ตัวอย่างเช่นหากระบบสันนิษฐานว่าไฟล์ข้อมูลลูกค้าจะไม่มีระเบียนมากกว่า 50,000 รายการโปรแกรมอาจมีการยืนยันว่าจำนวนระเบียนน้อยกว่าหรือเท่ากับ 50,000 ตราบใดที่จำนวนของระเบียนน้อยกว่าหรือเท่ากับ 50,000 การยืนยันจะเงียบ หากพบมากกว่า 50,000 เร็กคอร์ดมันจะดัง "ยืนยัน" ว่ามีข้อผิดพลาดในโปรแกรม

การยืนยันเป็นประโยชน์อย่างยิ่งในโปรแกรมขนาดใหญ่ซับซ้อนและในโปรแกรมที่มีความน่าเชื่อถือสูง พวกเขาทำให้โปรแกรมเมอร์สามารถกำจัดข้อสันนิษฐานของอินเตอร์เฟสที่ไม่ตรงกันอย่างรวดเร็วยิ่งขึ้นข้อผิดพลาดที่คืบคลานเข้ามาเมื่อมีการแก้ไขโค้ดและอื่น ๆ

การยืนยันมักจะใช้เวลาสองข้อโต้แย้ง: นิพจน์บูลีนที่อธิบายถึงข้อสมมติที่ควรจะเป็นจริงและข้อความที่จะแสดงถ้ามันไม่ได้

( ... )

โดยปกติคุณไม่ต้องการให้ผู้ใช้เห็นข้อความยืนยันในรหัสการผลิต การยืนยันเป็นหลักเพื่อใช้ในระหว่างการพัฒนาและการบำรุงรักษา โดยทั่วไปการยืนยันจะถูกรวบรวมเป็นรหัสในเวลาการพัฒนาและรวบรวมจากรหัสสำหรับการผลิต ในระหว่างการพัฒนาการยืนยันจะล้างออกสมมติฐานที่ขัดแย้งเงื่อนไขที่ไม่คาดคิดค่าที่ไม่ถูกต้องถูกส่งไปยังงานประจำและอื่น ๆ ในระหว่างการผลิตพวกเขาจะรวบรวมจากรหัสเพื่อให้ยืนยันไม่ลดประสิทธิภาพของระบบ


2
หนังสือเขียน Solid Code ยังมีการอภิปรายที่ดีเกี่ยวกับการใช้งานของยืนยัน พวกเขาเป็นเครื่องมือดีบั๊ก!
zooropa

39

คุณควรใช้มันหลายครั้งเมื่อคุณไม่ต้องการที่จะเบรกพอยต์ทุก ๆ บรรทัดของโค้ดเพื่อตรวจสอบตัวแปร แต่คุณต้องการได้รับผลตอบรับบางอย่างถ้ามีสถานการณ์บางอย่างเกิดขึ้นตัวอย่างเช่น

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");

หากฉันเพิ่มบรรทัดของรหัสที่คล้ายกับของคุณด้านบนการเรียกใช้โปรแกรมของฉันให้ข้อผิดพลาดต่อไปนี้: "ข้อผิดพลาด CS0103: ชื่อ 'Debug' ไม่มีอยู่ในบริบทปัจจุบัน" ฉันต้องใช้ข้อความเพื่อทำให้มันทำงานได้ไหม?
Josh Desmond

4
@JoshDesmondSystem.Diagnostics
Sinjai

16

Assert ยังเปิดโอกาสให้คุณหัวเราะเยาะทักษะการออกแบบ UI ของ Microsoft อีกครั้ง ฉันหมายถึง: กล่องโต้ตอบที่มีสามปุ่มยกเลิก, ลองใหม่, ไม่ต้องสนใจและคำอธิบายวิธีตีความในแถบหัวเรื่อง!


3
ยกเลิก / ลองใหม่ / ข้ามเป็นคลาสสิก! มันเป็นการยืนยันที่เคยทำให้ Windows 3.1 แสดงผลตลอดเวลาหรือไม่?
devlord

โดยทั่วไปมันเป็นเพราะมันใช้ MessageBox ซึ่งตามที่คุณบอกว่าวันที่กลับไปเป็น Windows 3.1 และมีป้ายชื่อปุ่มที่กำหนดไว้ล่วงหน้าเท่านั้น ดังนั้นคุณสามารถเข้าใจว่าทำไมการแฮ็คถึงมา แต่ไม่ใช่เหตุผลที่แฮ็กยังคงอยู่ในปี 2008
โจ

4
@ Joe นี่คือสิ่งที่ผู้พัฒนาควรเห็นไม่ใช่ผู้ใช้เท่านั้นดังนั้นการอัปเดตอาจเป็นรายการที่มีลำดับความสำคัญต่ำมาก ถ้ามันรบกวนคุณคุณสามารถแก้ไขคอลเลกชัน Debug.Listeners หรือ Trace.Listeners เพื่อแทนที่ตัวจัดการเริ่มต้นด้วยอันที่ทำสิ่งที่คุณต้องการ
Dan Is Fiddling โดย Firelight

5
และตอนนี้ก็เป็นปี 2019 และกล่องโต้ตอบ / ปุ่มเดียวกันยังคงอยู่ที่นี่!
Bouke

10

Assert ช่วยให้คุณสามารถยืนยันเงื่อนไข (โพสต์หรือ pre) ในรหัสของคุณ เป็นวิธีการบันทึกความตั้งใจของคุณและให้ดีบักเกอร์แจ้งให้คุณทราบพร้อมกล่องโต้ตอบหากไม่ได้ตั้งใจ

Assert จะไปพร้อมกับรหัสของคุณและสามารถใช้เพื่อเพิ่มรายละเอียดเพิ่มเติมเกี่ยวกับความตั้งใจของคุณ


10

Assert สามารถช่วยคุณกำหนดพฤติกรรมการส่งข้อความแยกต่างหากระหว่างการทดสอบและการเปิดตัว ตัวอย่างเช่น,

Debug.Assert(x > 2)

จะทำให้เกิดการหยุดพักหากคุณใช้งานบิลด์ "debug" ไม่ใช่บิลด์ออก มีตัวอย่างเต็มของพฤติกรรมนี้ที่นี่


10

วิธีแรกของทั้งหมดAssert()พร้อมใช้งานสำหรับTraceและDebugคลาส
Debug.Assert()กำลังดำเนินการในโหมดดีบักเท่านั้น
Trace.Assert()กำลังดำเนินการในโหมดดีบั๊กและรีลีส

นี่คือตัวอย่าง:

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

เรียกใช้รหัสนี้ในโหมด Debug และจากนั้นในโหมด Release

ป้อนคำอธิบายรูปภาพที่นี่

คุณจะสังเกตเห็นว่าในระหว่างโหมดดีบั๊กDebug.Assertคำสั่งรหัสของคุณล้มเหลวคุณจะได้รับกล่องข้อความแสดงการติดตามสแต็กปัจจุบันของแอปพลิเคชัน นี้ไม่ได้เกิดขึ้นในโหมดที่วางจำหน่ายตั้งแต่สภาพที่เป็นจริงTrace.Assert()(i == 4)

WriteLine() วิธีการเพียงให้ตัวเลือกในการบันทึกข้อมูลไปยังเอาต์พุต Visual Studio ป้อนคำอธิบายรูปภาพที่นี่


5

คุณสมบัติการยืนยันอย่างมากใน Design by Contract (DbC) ซึ่งฉันเข้าใจว่าถูกนำเสนอ / รับรองโดย Meyer, Bertand 1997. การสร้างซอฟต์แวร์เชิงวัตถุ

คุณลักษณะที่สำคัญคือพวกเขาจะต้องไม่สร้างผลข้างเคียงตัวอย่างเช่นคุณสามารถจัดการกับข้อยกเว้นหรือใช้แนวทางปฏิบัติที่แตกต่างกันโดยใช้คำสั่ง if (การตั้งโปรแกรมป้องกัน)

การยืนยันใช้เพื่อตรวจสอบเงื่อนไขก่อน / หลังของสัญญาความสัมพันธ์กับลูกค้า / ผู้จัดหา - ลูกค้าจะต้องตรวจสอบให้แน่ใจว่ามีการปฏิบัติตามเงื่อนไขล่วงหน้าของผู้จัดหาเช่น ส่ง£ 5 และซัพพลายเออร์จะต้องตรวจสอบให้แน่ใจว่าโพสต์เงื่อนไขตรงเช่น ส่งดอกกุหลาบ 12 ดอก (คำอธิบายง่ายๆของลูกค้า / ผู้จำหน่าย - สามารถยอมรับได้น้อยลงและให้มากขึ้น แต่เกี่ยวกับการยืนยัน) C # ยังแนะนำ Trace.Assert () ซึ่งสามารถใช้สำหรับรหัสการเปิดตัว

เพื่อตอบคำถามว่าใช่พวกเขายังมีประโยชน์ แต่สามารถเพิ่มความซับซ้อน + อ่านรหัสและเวลา + ยากที่จะรักษา เราควรจะใช้มันยังไง? ใช่เราทุกคนจะใช้พวกเขา? อาจไม่หรือไม่เท่าที่ Meyer อธิบาย

(แม้แต่หลักสูตร OU Java ที่ฉันได้เรียนรู้เทคนิคนี้เพียงแสดงตัวอย่างง่ายๆและส่วนที่เหลือของรหัสไม่ได้บังคับใช้กฎการยืนยัน DbC ในรหัสส่วนใหญ่ แต่ถูกสันนิษฐานว่าใช้เพื่อรับรองความถูกต้องของโปรแกรม!)


3

วิธีที่ฉันคิดว่ามันคือ Debug.Assert คือวิธีสร้างสัญญาเกี่ยวกับวิธีเรียกใช้วิธีการโดยมุ่งเน้นไปที่ข้อมูลเฉพาะเกี่ยวกับค่าของพารามิเตอร์ (แทนที่จะเป็นแค่ประเภท) ตัวอย่างเช่นถ้าคุณไม่ควรส่งค่า null ในพารามิเตอร์ตัวที่สองคุณเพิ่ม Assert รอบพารามิเตอร์นั้นเพื่อบอกให้ผู้บริโภคไม่ทำเช่นนั้น

มันป้องกันไม่ให้ใครบางคนใช้รหัสของคุณในทางที่น่ากลัว แต่มันยังช่วยให้วิธีการที่จะนำไปสู่การผลิตและไม่ให้ข้อความที่น่ารังเกียจแก่ลูกค้า (สมมติว่าคุณสร้าง Build build)


6
สิ่งสำคัญคือต้องชี้ให้เห็นว่าพารามิเตอร์ที่ไม่ถูกต้องในวิธีการสาธารณะควรโยนข้อยกเว้นการโต้แย้ง เฉพาะวิธีการส่วนตัวควรตรวจสอบความถูกต้องของข้อมูลด้วยการยืนยัน ค่าที่มาจากภายนอกมักจะสงสัยอยู่เสมอ!
Jeffrey L Whitledge
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.