ApplicationException คืออะไรใน. NET


172

จะโยนข้อยกเว้นผมมักจะใช้ในตัวชั้นเรียนข้อยกเว้นเช่นและArgumentNullException NotSupportedExceptionอย่างไรก็ตามบางครั้งฉันจำเป็นต้องใช้ข้อยกเว้นที่กำหนดเองและในกรณีที่ฉันเขียน:

class SlippedOnABananaException : Exception { }
class ChokedOnAnAppleException : Exception { }

และอื่น ๆ จากนั้นฉันก็โยนและจับสิ่งเหล่านี้ในรหัสของฉัน แต่วันนี้ฉันเข้าApplicationExceptionเรียน - ฉันควรจะใช้สิ่งนั้นแทนหรือไม่? เพื่ออะไร

ดูเหมือนไม่มีประสิทธิภาพที่จะมีคลาส Exception ที่เหมือนกันอย่างมีประสิทธิภาพจำนวนมากที่มีชื่อต่างกัน (โดยปกติฉันไม่ต้องการฟังก์ชันใด ๆ เลย) แต่ฉันไม่ชอบความคิดที่จะจับรหัสทั่วไปApplicationExceptionและต้องใช้รหัสพิเศษเพื่อพิจารณาว่าข้อผิดพลาดคืออะไร

ApplicationExceptionรหัสของฉันควรตรงกับที่ใด?


35
เป็นคำถามที่ดี +1 สำหรับข้อยกเว้นตัวอย่างที่มีชื่ออย่างชาญฉลาด
Cody Gray

ที่เกี่ยวข้อง: stackoverflow.com/questions/16603065/… .

คำตอบ:


100

ตามข้อสังเกตใน msdn:

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

หากคุณกำลังออกแบบแอปพลิเคชันที่ต้องการสร้างข้อยกเว้นของตัวเองคุณจะได้รับคำแนะนำให้รับข้อยกเว้นแบบกำหนดเองจากคลาสข้อยกเว้น แต่เดิมคิดว่าข้อยกเว้นที่กำหนดเองควรมาจากคลาส ApplicationException อย่างไรก็ตามในทางปฏิบัติสิ่งนี้ไม่พบว่าเพิ่มคุณค่าที่สำคัญ สำหรับข้อมูลเพิ่มเติมดูวิธีปฏิบัติที่ดีที่สุดสำหรับการจัดการข้อยกเว้น

Exceptionสืบทอดมาจากพวกเขา นอกจากนี้ฉันไม่เห็นปัญหาในการสร้างข้อยกเว้นใหม่สำหรับกรณีของคุณตราบใดที่มีการรับประกัน หากคุณพบกรณีที่มีข้อยกเว้นในกรอบอยู่แล้วให้ใช้ตัวคุณเอง


9
ดังนั้นดูเหมือนว่าApplicationExceptionไร้ประโยชน์และมีเพียงเพราะความเข้ากันได้ย้อนหลัง?
Beatles1692

เอกสาร MSDN ใหม่อย่างน้อย 4.7.2 ไม่มีคำพูดนี้ ขอบคุณสำหรับ qutoe: D
Alex

147

คำตอบสั้น ๆ คือ: ไม่มีที่ไหนเลย

เป็นที่ระลึกถึงอดีตที่ Microsoft ตั้งใจให้นักพัฒนาได้รับข้อยกเว้นที่กำหนดเองทั้งหมดจาก ApplicationException หลังจากนั้นไม่นานพวกเขาเปลี่ยนใจและแนะนำว่าข้อยกเว้นที่กำหนดเองควรได้รับจากคลาส Exception ดูวิธีปฏิบัติที่ดีที่สุดสำหรับการจัดการข้อยกเว้นใน MSDN

หนึ่งในเหตุผลที่แพร่หลายมากขึ้นสำหรับเรื่องนี้มาจาก exerpt จาก Jeffery Richter ในแนวทางการออกแบบกรอบ :

System.ApplicationExceptionเป็นคลาสที่ไม่ควรเป็นส่วนหนึ่งของ. NET Framework ความคิดเดิมเป็นชั้นเรียนที่มาจากSystemExceptionจะระบุข้อยกเว้นโยนจาก CLR (หรือระบบ) ตัวเองในขณะที่ข้อยกเว้นที่ไม่ CLR จะได้รับจากApplicationException อย่างไรก็ตามคลาสยกเว้นจำนวนมากไม่เป็นไปตามรูปแบบนี้ ยกตัวอย่างเช่นTargetInvocationException (ซึ่งก็คือโยนโดย CLR) จะมาจากApplicationException ดังนั้นคลาสApplicationExceptionสูญเสียความหมายทั้งหมด เหตุผลที่ได้รับมาจากคลาสพื้นฐานนี้คือการอนุญาตให้โค้ดที่สูงกว่าสแต็คการเรียกบางอย่างที่จะจับคลาสฐาน ไม่สามารถตรวจจับข้อยกเว้นของแอปพลิเคชันทั้งหมดได้อีกต่อไป

ดังนั้นคุณมีมัน บทสรุปผู้บริหารคือ ApplicationException ไม่เป็นอันตรายเพียงแค่ไร้ประโยชน์


2
ไม่มีใครรู้ว่าทำไมนั่นคือ? ดูเหมือนว่าจะสมเหตุสมผลเพื่อให้คุณสามารถแสดงข้อยกเว้นของแอป แต่ไม่ใช่ "ข้อผิดพลาดของโปรแกรมเมอร์"
Josh Kodroff

9
BTW ดูเหมือนว่าจากคำอธิบายนี้ว่านี่ไม่ใช่การออกแบบที่ไม่ดีต่อกัน แต่ MSFT ทำให้การติดตั้งล้มเหลว ไม่มีใครอ่านสิ่งนี้ในทำนองเดียวกัน?
Josh Kodroff

8
@JoshKodroff: ฉันคิดว่าปัญหาคือถ้าแอปพลิเคชั่นWhizbangตัดสินใจว่าต้องการให้มีข้อยกเว้นทั้งหมดภายใต้ลำดับชั้นทั่วไปบางอย่างการใช้ApplicationExceptionเพื่อจุดประสงค์นั้นจะไม่ให้ความได้เปรียบมากกว่าการใช้WhizbangExceptionคลาสพื้นฐานที่กำหนดเอง ปัญหาที่ร้ายแรงยิ่งขึ้นในลำดับชั้นข้อยกเว้นของ. net ไม่ได้อยู่ที่ApplicationExceptionแต่ด้วยความล้มเหลวในการแยกข้อยกเว้นออกเป็นประเภทที่อาจเป็นแอพพลิเคชั่นที่ร้ายแรงอาจเป็นเธรดที่ร้ายแรงและที่เกี่ยวข้องกับปัญหาในท้องถิ่น ข้อยกเว้น "คอมโพสิต" ที่มีความหมาย
supercat

@JoshKodroff: ในกรอบข้อยกเว้นที่ได้รับการออกแบบอย่างเหมาะสม IMHO หากมีข้อผิดพลาดเกิดขึ้นระหว่างการfinallyบล็อกในขณะที่มีข้อยกเว้นอื่นอยู่ระหว่างการรอการcatchบล็อกการตั้งค่าการเรียกสแต็กเพิ่มเติมควรตรงกับข้อยกเว้นใด ๆcatchบล็อกจะดำเนินการต่อไปอีกcatchบล็อกภายในเดียวกันtryบล็อก (ถ้ามีความเหมาะสม) และออกfinallyบล็อกที่มีข้อยกเว้นใด ๆ ที่ค้างอยู่จะข้ามไปยังด้านนอกต่อไปหรือcatch finally
supercat

2
@JoshKodroff มีอีกสิ่งหนึ่งที่ฉันประหลาดใจไม่ได้รับความสนใจมากขึ้น "แอปพลิเคชัน" คืออะไรจริง ๆ แล้วห้องสมุดบุคคลที่สามล่ะ เนื่องจากสิ่งเหล่านี้ไม่ได้เป็นส่วนหนึ่งของกรอบงาน. Net จึงควรมีแนวทางดั้งเดิมที่สืบทอดมาจาก ApplicationException ตอนนี้เมื่อคุณใช้ไลบรารีนั้นในแอปพลิเคชันของคุณและสร้าง ApplicationExceptions ของคุณเองคุณจะไม่สามารถแยกแยะข้อยกเว้นของคุณเองจากข้อยกเว้นของไลบรารี่อีกต่อไป ดังนั้นมันจึงไร้ประโยชน์ แต่ละองค์ประกอบควรกำหนดประเภทฐานข้อยกเว้นของตัวเองตามที่อธิบายไว้ใน supercat
Oskar Berggren

22

ในการออกแบบเริ่มต้นใน. NET 1.0 มีการวางแผนว่ากรอบตัวเองจะโยนSystemExceptionและรับ ขณะที่แอปพลิเคชันของผู้ใช้ - จะโยนApplicationExceptionและรับ

แต่ต่อมาใน. NET 2.0 ที่ถูกทิ้งไป

Exceptionดังนั้นจึงเป็นผลมาจาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.