Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用返回值包含错误的设计模式_C#_Design Patterns_Exception Handling_Error Logging - Fatal编程技术网

C# 使用返回值包含错误的设计模式

C# 使用返回值包含错误的设计模式,c#,design-patterns,exception-handling,error-logging,C#,Design Patterns,Exception Handling,Error Logging,我正在通过API为另一个软件编写外接程序。API返回的类只能通过本机软件和API访问。因此,我正在编写自己的独立POCO/DTO对象,这些对象映射到API类。我正在开发一个功能,它将读取一个本机文件,并返回这些POCO对象的集合,我可以从别处窃取这些对象。目前我正在使用JSON.NET将这些类序列化为JSON(如果有必要的话) 例如,我可能有这样的DTO public class MyPersonDTO { public string Name {get; set;} publi

我正在通过API为另一个软件编写外接程序。API返回的类只能通过本机软件和API访问。因此,我正在编写自己的独立POCO/DTO对象,这些对象映射到API类。我正在开发一个功能,它将读取一个本机文件,并返回这些POCO对象的集合,我可以从别处窃取这些对象。目前我正在使用JSON.NET将这些类序列化为JSON(如果有必要的话)

例如,我可能有这样的DTO

public class MyPersonDTO
{
    public string Name {get; set;}
    public string Age {get; set;}
    public string Address {get; set;}       
}
…还有这样一种方法,可以将本地“Persons”读入我的DTO对象

public static class MyDocReader
{
    public static IList<MyPersonDTO> GetPersons(NativeDocument doc)
    {
        //Code to read Persons from doc and return MyPersonDTOs
    }
}
公共静态类MyDocReader
{
公共静态IList GetPersons(NativeDocument文档)
{
//从文档中读取人员并返回MyPersonDTOs的代码
}
}
我用一个测试文件设置了单元测试,但是在其他文件上运行导出时,我总是遇到意外问题。有时本机对象会有意外的值,或者API中会出现完全错误,在没有理由的情况下抛出异常

当前,当发生“异常”时,我只记录异常,导出失败。但我决定,我宁愿导出我能导出的,并在某个地方记录错误

最简单的选择是只记录并吞下异常,然后返回我能返回的内容,但是我的调用代码无法知道什么时候出现了问题

我正在考虑的一个选项是将错误字典作为一个单独的参数返回。该键将标识无法读取的属性,该值将包含异常/错误的详细信息

public static class MyDocReader
{
    public static IList<MyPersonDTO> persons GetPersons(NativeDocument doc, out IDictionary<string, string> errors)
    {
        //Code to read persons from doc
    }
}
公共静态类MyDocReader
{
公共静态IList persons GetPersons(NativeDocument文档,out IDictionary错误)
{
//从文档中读取人员的代码
}
}
或者,我还考虑将错误存储在返回对象本身中。这会增大对象的大小,但还有一个额外的好处,那就是将错误直接存储在对象中。因此,如果以后有人的导出生成错误,我不必担心在他们的计算机上跟踪正确的日志文件

public class MyPersonDTO
{
    public string Name {get; set;}
    public string Age {get; set;}
    public string Address {get; set;}

    public IDictionary<string, string> Errors {get; set;}   
}
公共类MyPersondo
{
公共字符串名称{get;set;}
公共字符串年龄{get;set;}
公共字符串地址{get;set;}
公共IDictionary错误{get;set;}
}

这通常是如何处理的?是否有其他选项可以报告我没有考虑的错误和返回值?

而不是将错误作为实体的一部分返回,您可以将结果包装在回复或响应消息中。然后,错误可能是响应消息的一部分,而不是实体

这样做的好处是实体是干净的

缺点是很难将错误映射回有问题的实体/属性


当发送成批的实体时,这种缺点可能是一个大问题。当API更面向单个实体时,它就没有那么重要了。

原则上,如果API出现错误(无法恢复),调用代码必须知道发生了异常。因此,它可以有一个适当的战略来应对它

因此,我想到的方法受到了相同哲学的影响-

1> 定义您自己的异常,比如说
IncompleteReadException
。 该异常应有一个属性
IList
,用于存储异常发生前读取的记录

public class IncompleteReadException : Exception
{
    IList<MyPersonDTO> RecordsRead { get; private set; }       

   public IncompleteReadException(string message, IList<MyPersonDTO> recordsRead, Exception innerException) : base(message,innerException)
    {
        this.RecordsRead = recordsRead;
    }
}
公共类不完整ReadException:异常
{
IList记录读取{get;private set;}
public IncompleteReadException(字符串消息,IList记录读取,异常innerException):基(消息,innerException)
{
this.RecordsRead=RecordsRead;
}
}
2> 当读取时发生异常时,您可以捕获原始异常,将原始异常包装在此异常中并抛出
IncompleteReadException


这将允许调用代码(应用程序代码)在不完整的数据被读取时有一个策略来处理这种情况。

取决于实现,Martin Fowler认为最后一个选项是最有效的。还有一种异常方式,当出现问题时抛出异常。你是否碰巧有一个指向Martin讨论此问题的博客文章或演示文稿的链接?这篇文章有一个链接:你也可以执行回调(委托/lambda)或事件。这是一个很好的选择,但不幸的是,我很少处理单个对象。最典型的用例是比较来自两个单独文件的多个对象导出。我还几乎总是将返回的对象序列化为JSON,稍后再处理该JSON。因此,单独存储错误会有问题。我相信他的意思是您将返回
ParseResponse
,它被定义为
public class ParseResponse{public-IList-Persons{get;set;}public-IList-Exceptions{get;set;}}
然后您可以序列化return.Persons,它将不包含任何状态/返回代码数据。是的,这就是我的意思