Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.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# - Fatal编程技术网

C# 当存在接口和继承时,如何设计异常类

C# 当存在接口和继承时,如何设计异常类,c#,C#,问题如下,假设我想从一些文件中读取一些重要数据。一些重要的数据可以在文本文件和XML文件中找到,因此我将制作一个简单的接口 public interface SIDReader { void Open(); string GetSID(); void Close(); } public class TextSIDReader : SIDReader { ... override methods with text specific parsing } public

问题如下,假设我想从一些文件中读取一些重要数据。一些重要的数据可以在文本文件和XML文件中找到,因此我将制作一个简单的接口

public interface SIDReader
{
   void Open();
   string GetSID();
   void Close();
}


public class TextSIDReader : SIDReader
{
   ... override methods with text specific parsing
}

public class XmlSIDReader: SIDReader
{
   ... override methods with xmlspecific parsing
}
问题在于抛出可能出现的异常,比如当我们使用Open()方法时。在这种方法中,文本读取器方法只需在内存中打开该文件,而XML版本将首先检查该文件是否为有效的XML文件,然后执行一些其他检查并将其加载到树中。如何为这种情况设计例外情况?是否存在一些可能不适用于这两种情况的一般例外情况,或者是否存在一些特定例外情况?让我用一点代码更清楚地说明:

  SIDReader reader = new XmlSIDReader();
  try
  {
     reader.Open();
  } // generic exceptions
  catch(ParsingException)   // a exception that may arise only for the XML version, let's say when loading the tree    
  { 
      // tell the user you have a parsing exception so the file might be corrupt 
  }
  catch(DataIntegrityException) // again something specific for XML's
或者更具体的事情

  SIDReader reader = new XmlSIDReader();
  try
  {
     reader.Open();
  } // specific exceptions
  catch(XmlTreeLoadException)      
  { 
      // tell the user you have a tree loading exception so the file might be corrupt 
  }
  catch(TextReaderException) // something specific for text parsers
我知道这听起来像是一个简单的命名问题,但对于一般异常,如果您想向用户报告xml树无效,那么在ParsingException的catch子句中,您必须检查使用了什么解析器,并相应地格式化错误消息(“xml数据无效”)在这种情况下,对于文本读者来说,没有什么可报告的。如果您使用特定的异常,您确切地知道要报告什么,因为您已经知道失败的是什么,但是您将抽象泄漏到了所有地方


什么方法更好,或者有什么替代方案?语言是C#,但这是一个相当普遍的问题

您可以将异常类和异常类注入到每个子类中,比如TextSIDReader类

public interface IExceptionHandler
{
    void HandleException(Exception exception);
}

public class TextSIDExceptionHandler : IExceptionHandler
{
    public void HandleException(Exception exception)
    {
        //do whatever you want with the exception, you can try to cast it to specific exception type and act according type
    }
}

public interface SIDReader
{
   void Open();
   string GetSID();
   void Close();
}

public class TextSIDReader : SIDReader
{
   private IExceptionHandler _exceptionHandler;

    public void TextSIDReader(IExceptionHandler exceptionHandler)
    {
        _exceptionHandler = exceptionHandler;
    }

    public void Open()
    {
        try
        {

        }
        catch (Exception ex)
        {
            _exceptionHandler.HandleException(ex);
        }
    }

    public string GetSID()
    {
        throw new NotImplementedException();
    }

    public void Close()
    {
        throw new NotImplementedException();
    }
}

您可以将异常类和异常类注入到每个子类中,比如TextSIDReader类

public interface IExceptionHandler
{
    void HandleException(Exception exception);
}

public class TextSIDExceptionHandler : IExceptionHandler
{
    public void HandleException(Exception exception)
    {
        //do whatever you want with the exception, you can try to cast it to specific exception type and act according type
    }
}

public interface SIDReader
{
   void Open();
   string GetSID();
   void Close();
}

public class TextSIDReader : SIDReader
{
   private IExceptionHandler _exceptionHandler;

    public void TextSIDReader(IExceptionHandler exceptionHandler)
    {
        _exceptionHandler = exceptionHandler;
    }

    public void Open()
    {
        try
        {

        }
        catch (Exception ex)
        {
            _exceptionHandler.HandleException(ex);
        }
    }

    public string GetSID()
    {
        throw new NotImplementedException();
    }

    public void Close()
    {
        throw new NotImplementedException();
    }
}
你的问题改为: 我的代码应该在什么抽象级别抛出异常


恰当的答案是: 异常的抽象级别应与异常所在例程的接口抽象一致 情况已经发生

在您的案例中,当您说这是一个命名问题时,您显示出朝着正确方向思考的提示。非常接近。。。这是一个抽象问题

所以,

  • 如果有人在您的接口级别
    SIDReader
    工作,并且在
    Open()
    中发生异常,则异常应该表示无法从SIDReader读取,并且应该从实现此
    SIDReader
    接口的实际类中具有InnerException,即
    XmlSIDReader
    TextSIDReader
  • 如果此人在您的
    XmlSIDReader
    级别工作,并且该类中的
    Open()
    中发生异常,则异常消息应表示无法打开Xml文件。。废话废话
  • 如果该人员在您的
    TestSIDReader
    级别工作,并且该类中的
    Open()
    中发生异常,则异常消息应表示无法打开文本文件,依此类推
这种理解也可以进一步渗透到其他各种方法中。例如,即使在
Open()
中调用了其他一些方法,并且异常发生在那里,那么这个方法也应该抛出自己的异常,准确地告诉自己的级别发生了什么。该异常可以由
Open()
封装,也可以由实现该
Open()
的实际类进一步封装


也考虑… 你应该总是考虑完整的错误处理技术:
  • 本地处理错误
  • 使用错误代码传播错误
  • 将调试信息记录到文件中
  • 关闭系统
  • 或者使用其他方法
  • 仅仅因为您的语言提供了异常处理,就用异常处理错误是、和的经典示例
  • “有时,对严重运行时错误的最佳响应是释放所有获取的资源并中止”-Bjarne Stroustrup

  • 这个答案的灵感来源于史蒂夫·麦康奈尔的传奇之作——代码完成2

    您的问题重新表述: 我的代码应该在什么抽象级别抛出异常


    恰当的答案是: 异常的抽象级别应与异常所在例程的接口抽象一致 情况已经发生

    在您的案例中,当您说这是一个命名问题时,您显示出朝着正确方向思考的提示。非常接近。。。这是一个抽象问题

    所以,

    • 如果有人在您的接口级别
      SIDReader
      工作,并且在
      Open()
      中发生异常,则异常应该表示无法从SIDReader读取,并且应该从实现此
      SIDReader
      接口的实际类中具有InnerException,即
      XmlSIDReader
      TextSIDReader
    • 如果此人在您的
      XmlSIDReader
      级别工作,并且该类中的
      Open()
      中发生异常,则异常消息应表示无法打开Xml文件。。废话废话
    • 如果该人员在您的
      TestSIDReader
      级别工作,并且该类中的
      Open()
      中发生异常,则异常消息应表示无法打开文本文件,依此类推
    这种理解也可以进一步渗透到其他各种方法中。例如,即使在
    Open()
    中调用了其他一些方法,并且异常发生在那里,那么这个方法也应该抛出自己的异常,准确地告诉它的