วิธีจัดทำเอกสารข้อยกเว้นใน c # /. net


139

ฉันกำลังเขียนกรอบเล็ก ๆ ที่จะใช้ภายในโดยนักพัฒนาอื่น ๆ ภายใน บริษัท

ฉันต้องการให้ข้อมูล Intellisense ที่ดี แต่ฉันไม่แน่ใจว่าจะบันทึกข้อยกเว้นได้อย่างไร

ในตัวอย่างต่อไปนี้:

public void MyMethod1()
{
    MyMethod2();

    // also may throw InvalidOperationException
}

public void MyMethod2()
{
    System.IO.File.Open(somepath...); // this may throw FileNotFoundException

    // also may throw DivideByZeroException
}

ฉันรู้ว่ามาร์กอัปสำหรับการยกเว้นเอกสารคือ:

/// <exception cref="SomeException">when things go wrong.</exception>

สิ่งที่ฉันไม่เข้าใจคือวิธีการจัดทำเอกสารข้อยกเว้นโยนโดยรหัสที่เรียกว่า MyMethod1() ?

  • ฉันควรบันทึกข้อยกเว้นที่ถูกส่งไปด้วยหรือไม่ MyMethod2()
  • ฉันควรบันทึกข้อยกเว้นที่ถูกส่งไปด้วยFile.Open()หรือไม่

อะไรจะเป็นวิธีที่ดีที่สุดในการบันทึกข้อยกเว้นที่เป็นไปได้


4
ฉันรู้ว่านี่ไม่ใช่สิ่งที่คุณถาม (และนี่เป็นคำถามที่เก่ามาก) แต่ Eric Lippert (นักพัฒนาหลักในคอมไพเลอร์และทีมออกแบบของ Microsoft C #) เขียนบทความในบล็อกเกี่ยวกับข้อยกเว้น 4 ประเภทที่ฉันคิดว่านักพัฒนาทุกคน ควรคิดในขณะที่เขียนรหัสการจัดการข้อยกเว้น: blogs.msdn.com/b/ericlippert/archive/2008/09/10/ …
javajavajavajavajava

@javajavajavajavajava ขอบคุณสำหรับลิงค์ - คุ้มค่าที่จะอ่าน
อาร์โนลด์ Zokas

ฉันคิดว่านี่เป็นคำถามที่ถูกต้องเพราะมันไม่ชัดเจนเลยว่าจะบันทึกข้อยกเว้นใน C # ได้อย่างไรและมุมมอง 50K แสดงให้เห็นว่ายังไม่ชัดเจนสำหรับคนจำนวนมาก คำตอบที่ได้รับการโหวตมากที่สุดอันดับสองนั้นมีประโยชน์มากเพราะมันแสดงให้เห็นว่าใช้ xmldocs ที่มีอยู่เพื่อทำเอกสารนี้ การลงคะแนนเพื่อเปิดใหม่ เหตุผลปิด "อิงตามความคิดเห็น" นี้คือการฆ่าคำถามการเขียนโปรแกรมที่มีประโยชน์มากจริง ๆ
Alexei

คำตอบ:


110

คุณควรบันทึกทุกข้อยกเว้นที่อาจเกิดจากรหัสของคุณรวมถึงข้อยกเว้นในวิธีการใด ๆ ที่คุณอาจเรียกใช้

หากรายการมีขนาดใหญ่ขึ้นคุณอาจต้องการสร้างประเภทการยกเว้นของคุณเอง จับทุกสิ่งที่คุณอาจพบในวิธีการของคุณห่อพวกเขาในข้อยกเว้นของคุณและโยนมัน

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


เพื่อตอบข้อกังวลของ Andrew (จากความคิดเห็น) มีข้อยกเว้นสามประเภท: คนที่คุณไม่รู้จักคนที่คุณรู้จักและไม่สามารถทำอะไรได้และคนที่คุณรู้และสามารถทำอะไรบางอย่างได้

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

สิ่งที่คุณรู้และไม่สามารถทำอะไรได้เป็นข้อยกเว้นเช่น OutOfMemoryExceptions ในกรณีที่รุนแรงคุณอาจต้องการจัดการกับข้อยกเว้นเช่นนี้ แต่ถ้าคุณมีข้อกำหนดที่น่าทึ่งคุณควรปฏิบัติต่อพวกเขาเหมือนหมวดหมู่แรก - ปล่อยมันไป คุณต้องทำเอกสารข้อยกเว้นเหล่านี้หรือไม่? คุณจะดูเอกสาร OOMs ที่ค่อนข้างโง่ในทุก ๆ วิธีที่สร้างวัตถุขึ้นมาใหม่

สิ่งที่คุณรู้และสามารถทำอะไรบางอย่างเกี่ยวกับสิ่งที่คุณควรบันทึกและห่อ

คุณสามารถหาแนวทางเพิ่มเติมเกี่ยวกับการจัดการข้อยกเว้นได้ที่นี่


3
ฉันต้องยอมรับว่านี่ไม่ได้ฟังดูเป็นประโยชน์ ฉันไม่สามารถจินตนาการได้ว่ามีข้อยกเว้นที่เป็นไปได้จำนวนเท่าใดที่สามารถโยนได้โดยรหัสใด ๆ ที่ฉันอาจเรียกรวมทั้งมีสิ่งต่าง ๆ เช่น OutOfMemoryException ที่คุณไม่ต้องการจับและห่อหุ้มด้วย
Andrew Hare

3
คำตอบของคุณจะดีหรือไม่ แต่จริงๆแล้วมันเป็นสองคำตอบที่ขัดแย้งกัน "จัดทำเอกสารทุกข้อยกเว้นที่อาจถูกโยนด้วยรหัสของคุณ" และ "สิ่งที่คุณรู้และสามารถทำบางสิ่งได้เป็นสิ่งที่คุณควรบันทึกไว้"
tymtam

2
@Tymek: ไม่ ครึ่งแรกตอบคำถาม "ฉันควรทำอย่างไรเอกสารข้อยกเว้น" ส่วนที่สองชี้ให้เห็นคำตอบที่ชัดเจนอย่างชัดเจนว่า "ฉันควรทำเอกสารอะไรยกเว้น" ข้อแรกไม่ได้หมายความว่าคุณบันทึกเอกสารทุกข้อยกเว้นที่อาจเกิดขึ้นได้ บางคนมีตัวอักษรมากเกินไปซึ่งต้องการครึ่งหลัง

5
@Tekek ฉันคิดว่าจุดของคุณอาจเป็นได้ว่าถ้าคุณสามารถทำอะไรกับมันได้ทำไมไม่ทำอะไรกับมันแทนที่จะทำมันใหม่แล้วทำมันอีกล่ะ? อาจเป็นเรื่องจริงมากกว่าที่จะพูดว่า "สิ่งที่คุณรู้เกี่ยวกับว่ารหัสลูกค้าสามารถทำอะไรบางอย่างเกี่ยวกับ" สิ่งนี้จะลบความขัดแย้งเนื่องจากสิ่งเหล่านี้เป็นข้อยกเว้นในอุดมคติสำหรับเอกสาร
โม

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

96

คุณควรใช้เอกสารมาตรฐาน XML

/// <exception cref="InvalidOperationException">Why it's thrown.</exception>
/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod1()
{
    MyMethod2();
    // ... other stuff here
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
/// <exception cref="DivideByZeroException">Why it's thrown.</exception>
public void MyMethod2()
{
    System.IO.File.Open(somepath...);
}

/// <exception cref="FileNotFoundException">Why it's thrown.</exception>
public void MyMethod3()
{
    try
    {
        MyMethod2();
    }
    catch (DivideByZeroException ex)
    {
        Trace.Warning("We tried to divide by zero, but we can continue.");
    }
}

ค่าในการทำเช่นนี้คือคุณกำลังเตรียมเอกสารของข้อยกเว้นที่รู้จักที่สามารถเกิดขึ้นได้ เอกสารนี้มีอยู่ใน Intellisense หากคุณใช้ Visual Studio และสามารถเตือนคุณ (หรือคนอื่น ๆ ) ภายหลังจากข้อยกเว้นที่คุณคาดหวัง

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


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

7
@ShiranGinige ประสบการณ์ของคุณผิด
Grozz

35

คุณสามารถทำให้กระบวนการเอกสารของคุณง่ายขึ้นโดยใช้ Add-in ที่ยอดเยี่ยมหลายรายการ หนึ่งในนั้นคือGhostDoc , Add-in ฟรีสำหรับ Visual Studio ซึ่งสร้างความคิดเห็น XML-doc นอกจากนี้หากคุณใช้ReSharperให้ดูที่Agent Johnson Plugin ที่ยอดเยี่ยมสำหรับ ReSharper ซึ่งจะเพิ่มตัวเลือกในการสร้างความคิดเห็น XML สำหรับข้อยกเว้นที่ส่งออกมา

อัปเดต:ดูเหมือนว่า Agen Johnson ไม่พร้อมใช้งานสำหรับ R # 8 เช็คเอาต์พิเศษสำหรับ ReSharperเป็นทางเลือก ...

ขั้นตอนที่ 1: GhostDoc สร้างข้อคิดเห็น XML (Ctrl-Shift-D) ในขณะที่ปลั๊กอิน Agent Johnson สำหรับ ReSharper แนะนำการบันทึกข้อยกเว้นเช่นกัน:

ขั้นตอนที่ 1

ขั้นตอนที่ 2: ใช้คีย์ลัดของ ReSharper (Alt-Enter) เพื่อเพิ่มเอกสารข้อยกเว้นเช่นกัน:

ขั้นตอนที่ 2 http://i41.tinypic.com/osdhm

หวังว่าจะช่วย :)


การเชื่อมโยง Tinypic เสีย
Aneves

11

จากสิ่งที่ฉันเข้าใจความตั้งใจในการใช้องค์ประกอบ <exception> คือการใช้มันเมื่อวิธีการตกแต่งไม่ใช่ข้อยกเว้น:

/// <summary>Does something!</summary>
/// <exception cref="DidNothingException">Thrown if nothing is actually done.</exception>
public void DoSomething()
{
// There be logic here
}

ข้อยกเว้นที่สามารถโยนได้ด้วยวิธีการอื่นที่เรียกว่าควรได้รับการจัดการและจัดทำเอกสารในวิธีการเหล่านั้น ข้อยกเว้นที่อาจถูกโยนโดย. NET หรือข้อยกเว้นที่ถูกส่งออกมาอย่างชัดเจนด้วยรหัสของคุณเองควรได้รับการบันทึกไว้

เท่าที่ได้รับเฉพาะเจาะจงมากไปกว่านั้นบางทีคุณสามารถจับและโยนข้อยกเว้นที่คุณกำหนดเองได้?


4

ส่วนหนึ่งของสัญญาสำหรับวิธีการของคุณควรตรวจสอบว่าเงื่อนไขล่วงหน้านั้นถูกต้องดังนั้น:

public void MyMethod2()
{
    System.IO.File.Open(somepath...); // this may throw FileNotFoundException
}

กลายเป็น

/// <exception cref="FileNotFoundException">Thrown when somepath isn't a real file.</exception>
public void MyMethod2()
{
    FileInfo fi = new FileInfo( somepath );
    if( !fi.Exists )
    {
        throw new FileNotFoundException("somepath doesn't exists")
    }
    // Maybe go on to check you have permissions to read from it.

    System.IO.File.Open(somepath...); // this may still throw FileNotFoundException though
}

ด้วยวิธีนี้มันง่ายกว่าที่จะทำเอกสารข้อยกเว้นทั้งหมดที่คุณโยนอย่างชัดเจนโดยไม่ต้องทำเอกสารว่าOutOfMemoryException อาจถูกโยนทิ้ง ฯลฯ


1
ไม่แน่ใจว่าประเด็นของการตรวจสอบคืออะไรถ้าคุณกำลังจะทำซ้ำข้อยกเว้นที่การOpenโทรจะส่งต่อไป (ไม่ต้องพูดถึงดังที่คุณทราบว่ามีการแข่งขันและการตรวจสอบไม่รับประกันความสำเร็จOpen) .
Matt Enright

1
@ MattEnright ที่ได้รับ แต่ฉันได้ทำสิ่งนี้เล็กน้อยเพื่อแสดงให้เห็นถึงจุด ...
Rowland Shaw

1

คุณควรบันทึกข้อยกเว้นทั้งหมดที่อาจเกิดขึ้นจากวิธีการของคุณ

หากต้องการซ่อนรายละเอียดการใช้งานฉันจะพยายามจัดการข้อยกเว้นบางอย่างจาก MyMethod2 ด้วยตนเอง

คุณสามารถลองทำการรีเคลมอีกครั้งหากคุณไม่สามารถจัดการหรือแก้ไขข้อยกเว้นได้ ส่วนใหญ่บรรจุ / ห่อด้วยข้อยกเว้นที่มีความหมายมากขึ้นสำหรับผู้โทร


1

แน่นอนตามที่ได้รับคำตอบแล้ววิธีการบันทึกข้อยกเว้นคือใช้ความคิดเห็นของ XML

นอกเหนือจากปลั๊กอินคุณยังสามารถใช้เครื่องมือวิเคราะห์แบบคงที่ที่สามารถรวมเข้ากับ TFS เพื่อให้แน่ใจว่าคุณมีเอกสารข้อยกเว้น

ในลิงก์ด้านล่างคุณสามารถดูวิธีสร้างกฎที่กำหนดเองสำหรับ StyleCop เพื่อตรวจสอบข้อยกเว้นที่เกิดขึ้นจากวิธีการของคุณ

http://www.josefcobonnin.com/post/2009/01/11/Xml-Documentation-Comments-Exceptions-I.aspx http://www.josefcobonnin.com/post/2009/01/15/Xml-Documentation -Comments-ข้อยกเว้น-II.aspx

ความนับถือ.


0

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

จำไว้ว่าเป็นการแจ้งให้ผู้โทรทราบถึงสิ่งที่คาดหวังเพื่อให้พวกเขาสามารถเลือกวิธีจัดการกับมัน

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