แก้ไข:ฉันเห็นด้วยกับคนอื่น ๆ ที่พูดว่าในฐานะของ C # 6.0 ตอนนี้ตัวกรองข้อยกเว้นเป็นวิธีที่ดีที่สุดที่จะไป:catch (Exception ex) when (ex is ... || ex is ... )
ยกเว้นว่าฉันยังคงเกลียดชังเลย์เอาท์แบบยาวหนึ่งบรรทัดและจะวางโค้ดเป็นการส่วนตัวดังต่อไปนี้ ฉันคิดว่ามันใช้งานได้ดีราวกับมันเป็นสุนทรียะเพราะฉันเชื่อว่ามันช่วยเพิ่มความเข้าใจ บางคนอาจไม่เห็นด้วย:
catch (Exception ex) when (
ex is ...
|| ex is ...
|| ex is ...
)
ORIGINAL:
ฉันรู้ว่าฉันมาช้าไปงานปาร์ตี้ที่นี่ แต่ควันศักดิ์สิทธิ์ ...
การตัดตรงไปที่การไล่ล่าการทำซ้ำคำตอบก่อนหน้านี้ แต่ถ้าคุณต้องการดำเนินการร่วมกันสำหรับประเภทข้อยกเว้นหลายประเภทและทำให้ทุกอย่างเรียบร้อยและเป็นระเบียบภายในขอบเขตของวิธีการหนึ่งทำไมไม่ใช้แลมบ์ดา ฟังก์ชันการปิด / / อินไลน์เพื่อทำสิ่งต่อไปนี้? ฉันหมายความว่ามีโอกาสค่อนข้างดีที่คุณจะรู้ว่าคุณเพียงแค่ต้องการทำให้การปิดเป็นวิธีแยกต่างหากที่คุณสามารถใช้ประโยชน์ได้ทั่วทุกที่ แต่มันจะเป็นเรื่องง่ายสุด ๆ โดยไม่ต้องเปลี่ยนส่วนที่เหลือของโครงสร้าง ขวา?
private void TestMethod ()
{
Action<Exception> errorHandler = ( ex ) => {
// write to a log, whatever...
};
try
{
// try some stuff
}
catch ( FormatException ex ) { errorHandler ( ex ); }
catch ( OverflowException ex ) { errorHandler ( ex ); }
catch ( ArgumentNullException ex ) { errorHandler ( ex ); }
}
ฉันอดไม่ได้ที่จะสงสัย ( คำเตือน:ประชดเล็ก ๆ น้อย ๆ / การประชดประชันข้างหน้า) ทำไมบนโลกถึงความพยายามทั้งหมดนี้โดยทั่วไปเพียงแค่แทนที่สิ่งต่อไปนี้:
try
{
// try some stuff
}
catch( FormatException ex ){}
catch( OverflowException ex ){}
catch( ArgumentNullException ex ){}
... ด้วยความแปรปรวนที่บ้าคลั่งของกลิ่นรหัสต่อไปนี้ฉันหมายถึงตัวอย่างเพียงแกล้งทำเป็นว่าคุณกำลังบันทึกการกดแป้นบางครั้ง
// sorta sucks, let's be honest...
try
{
// try some stuff
}
catch( Exception ex )
{
if (ex is FormatException ||
ex is OverflowException ||
ex is ArgumentNullException)
{
// write to a log, whatever...
return;
}
throw;
}
เพราะมันไม่สามารถอ่านได้โดยอัตโนมัติ
จริงอยู่ฉันออกจากอินสแตนซ์ที่เหมือนกันสามรายการ/* write to a log, whatever... */ return;
จากตัวอย่างแรก
แต่นั่นเป็นจุดของฉัน คุณเคยได้ยินฟังก์ชั่น / วิธีการใช่มั้ย อย่างจริงจัง. เขียนErrorHandler
ฟังก์ชั่นทั่วไปและเช่นเรียกมันจากแต่ละ catch block
หากคุณถามฉันตัวอย่างที่สอง (พร้อมกับif
และis
คำหลัก) มีทั้งที่อ่านได้น้อยลงและมีข้อผิดพลาดเกิดขึ้นได้ง่ายกว่าในระหว่างขั้นตอนการบำรุงรักษาของโครงการของคุณ
ขั้นตอนการบำรุงรักษาสำหรับผู้ที่อาจจะค่อนข้างใหม่ในการเขียนโปรแกรมจะประกอบด้วย 98.7% หรือมากกว่าของอายุการใช้งานโดยรวมของโครงการของคุณและ schmuck ที่ไม่ดีในการบำรุงรักษาเกือบจะแน่นอนเป็นคนอื่นที่ไม่ใช่คุณ และมีโอกาสที่ดีมากที่พวกเขาจะใช้เวลา 50% ในการสาปแช่งชื่อของคุณ
และแน่นอน FxCop เปลือกที่คุณและดังนั้นคุณต้องยังเพิ่มแอตทริบิวต์รหัสของคุณที่ได้อย่างแม่นยำ zip จะทำอย่างไรกับโปรแกรมการทำงานและเป็นเพียงมีจะบอก FxCop ที่จะไม่สนใจปัญหาที่ใน 99.9% ของกรณีมันเป็นโดยสิ้นเชิง แก้ไขในการตั้งค่าสถานะ และขออภัยฉันอาจเข้าใจผิด แต่แอตทริบิวต์ "เพิกเฉย" นั้นไม่ได้รวบรวมไว้ในแอปของคุณจริงหรือ
การวางการif
ทดสอบทั้งหมดในบรรทัดเดียวจะทำให้อ่านง่ายขึ้นหรือไม่ ฉันไม่คิดอย่างนั้น ฉันหมายความว่าฉันมีโปรแกรมเมอร์คนอื่นเถียงอีกครั้งเมื่อนานมาแล้วว่าการวางโค้ดเพิ่มเติมในบรรทัดเดียวจะทำให้ "ทำงานได้เร็วขึ้น" แต่แน่นอนว่าเขาเป็นคนบ้าคลั่ง พยายามอธิบายให้เขา (ด้วยหน้าตรง - ซึ่งท้าทาย) วิธีล่ามหรือคอมไพเลอร์จะแยกบรรทัดยาวนั้นออกเป็นคำสั่งหนึ่งคำสั่งต่อบรรทัดแยกกันโดยสิ้นเชิงเหมือนกับผลลัพธ์ถ้าเขาไปข้างหน้าและ เพิ่งทำให้โค้ดอ่านได้แทนที่จะพยายามคอมไพเลอร์ที่ฉลาด - ไม่มีผลอะไรกับเขาเลย แต่ฉันเชือนแช
สิ่งนี้จะอ่านได้น้อยลงเท่าใดเมื่อคุณเพิ่มประเภทข้อยกเว้นอีกสามประเภทเดือนหรือสองเดือนนับจากนี้ (คำตอบ: มันอ่านน้อยลงมาก )
หนึ่งในประเด็นสำคัญจริง ๆ ก็คือจุดส่วนใหญ่ของการจัดรูปแบบซอร์สโค้ดแบบข้อความที่เราทุกคนกำลังดูอยู่ทุกวันคือการทำให้มันชัดเจนจริงๆกับมนุษย์คนอื่น ๆ สิ่งที่เกิดขึ้นจริงเมื่อรหัสทำงาน เพราะคอมไพเลอร์เปลี่ยนซอร์สโค้ดให้เป็นอะไรที่ต่างออกไปโดยสิ้นเชิงและไม่สนใจสไตล์การจัดรูปแบบโค้ดของคุณน้อยลง ดังนั้น all-on-one-line ก็ดูดเหมือนกัน
แค่พูด...
// super sucks...
catch( Exception ex )
{
if ( ex is FormatException || ex is OverflowException || ex is ArgumentNullException )
{
// write to a log, whatever...
return;
}
throw;
}