ทุกครั้งที่ฉันต้องการให้ข้อมูลเพิ่มเติมเกี่ยวกับข้อยกเว้นที่ฉันสงสัยว่าวิธีใดเป็นวิธีที่ถูกต้องในการทำสิ่งนี้
เพื่อประโยชน์ของคำถามนี้ฉันได้เขียนตัวอย่าง สมมติว่ามีคลาสที่เราต้องการอัพเดตAbbreviationคุณสมบัติ จากมุมมองของโซลิดมันอาจจะไม่สมบูรณ์แบบ แต่แม้ว่าเราจะผ่านวิธีปฏิบัติงานผ่าน DI ด้วยบริการบางอย่างสถานการณ์เดียวกันก็จะเกิดขึ้น - มีข้อยกเว้นเกิดขึ้นและไม่มีบริบทใด ๆ เกิดขึ้น กลับไปที่ตัวอย่าง ...
class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Abbreviation { get; set; }
}
จากนั้นมีอินสแตนซ์ของคลาสและลูปที่เรียกเมธอดของผู้ปฏิบัติงาน StringTooShortExceptionมันสามารถโยน
var persons =
{
    new Person { Id = 1, Name = "Fo" },
    new Person { Id = 2, Name = "Barbaz" },
}
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
    foreach (var person in persons)
    {
        try
        {
            person.Abbreviation = GenerateAbbreviation(person.Name);
        }
        catch(Exception ex)
        {
            // ?
        }
    }
    // throw AggregateException...
}
public IEnumerable<string> GenerateAbbreviation(string value)
{
    if (value.Length < 5)
    {
        throw new StringTooShortException(value);
    }
    // generate abbreviation
}
คำถามคือ: วิธีการเพิ่มPersonหรือId(หรือสิ่งอื่นใด)?
ฉันรู้สามเทคนิคต่อไปนี้:
1 - ใช้Dataคุณสมบัติ
ข้อดี:
- ง่ายต่อการตั้งค่าข้อมูลเพิ่มเติม
- ไม่ต้องการการสร้างข้อยกเว้นเพิ่มเติม
- ไม่ต้องการเพิ่มเติม try/catch
จุดด้อย:
- ไม่สามารถรวมเข้ากับ Message
- คนตัดไม้เพิกเฉยฟิลด์นี้และจะไม่ทิ้งมัน
- ต้องใช้กุญแจและหล่อค่าได้เพราะ object
- ไม่เปลี่ยนรูป
ตัวอย่าง:
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
    foreach (var person in persons)
    {
        try
        {
            person.Abbreviation = GenerateAbbreviation(person.Name);
        }
        catch(Exception ex)
        {
            ex.Data["PersonId"] = person.Id;
            // collect ex
        }
    }
    // throw AggregateException...
}2 - ใช้คุณสมบัติที่กำหนดเอง
ข้อดี:
- คล้ายกับDataคุณสมบัติ แต่พิมพ์อย่างมาก
- ง่ายต่อการรวมเข้ากับ Message
จุดด้อย:
- ต้องมีข้อยกเว้นที่กำหนดเอง
- คนตัดไม้จะไม่สนใจพวกเขา
- ไม่เปลี่ยนรูป
ตัวอย่าง:
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
    foreach (var person in persons)
    {
        try
        {
            person.Abbreviation = GenerateAbbreviation(person.Name);
        }
        catch(Exception ex)
        {
            // not suitable for this exception because 
            // it doesn't have anything in common with the Person
        }
    }
    // throw AggregateException...
}3 - ตัดข้อยกเว้นด้วยข้อยกเว้นอื่น
ข้อดี:
- Messageสามารถจัดรูปแบบในวิธีที่คาดการณ์ได้
- คนตัดไม้จะถ่ายโอนข้อยกเว้นภายใน
- ไม่เปลี่ยนรูป
จุดด้อย:
- ต้องการเพิ่มเติม try/catch
- ทำรังซ้อน
- เพิ่มความลึกของการ exeptions
ตัวอย่าง:
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
    foreach (var person in persons)
    {
        try
        {
            try
            {
                person.Abbreviation = GenerateAbbreviation(person.Name);
            }
            catch(Exception ex)
            {
                throw new InvalidPersonDataException(person.Id, ex);
            }
        }
        catch(Exception ex)
        {
            // collect ex
        }
    }
    // throw AggregateException...
}- มีรูปแบบอื่น ๆ อีกไหม?
- มีรูปแบบที่ดีขึ้นหรือไม่
- คุณสามารถแนะนำวิธีปฏิบัติที่ดีที่สุดสำหรับพวกเขา / ทุกคน?