C# 当存在接口和继承时,如何设计异常类
问题如下,假设我想从一些文件中读取一些重要数据。一些重要的数据可以在文本文件和XML文件中找到,因此我将制作一个简单的接口C# 当存在接口和继承时,如何设计异常类,c#,C#,问题如下,假设我想从一些文件中读取一些重要数据。一些重要的数据可以在文本文件和XML文件中找到,因此我将制作一个简单的接口 public interface SIDReader { void Open(); string GetSID(); void Close(); } public class TextSIDReader : SIDReader { ... override methods with text specific parsing } public
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
中发生异常,则异常应该表示无法从SIDReader读取,并且应该从实现此Open()
接口的实际类中具有InnerException,即SIDReader
或XmlSIDReader
TextSIDReader
- 如果此人在您的
级别工作,并且该类中的XmlSIDReader
中发生异常,则异常消息应表示无法打开Xml文件。。废话废话Open()
- 如果该人员在您的
级别工作,并且该类中的TestSIDReader
中发生异常,则异常消息应表示无法打开文本文件,依此类推Open()
Open()
中调用了其他一些方法,并且异常发生在那里,那么这个方法也应该抛出自己的异常,准确地告诉自己的级别发生了什么。该异常可以由Open()
封装,也可以由实现该Open()
的实际类进一步封装
也考虑… 你应该总是考虑完整的错误处理技术:
这个答案的灵感来源于史蒂夫·麦康奈尔的传奇之作——代码完成2您的问题重新表述: 我的代码应该在什么抽象级别抛出异常
恰当的答案是: 异常的抽象级别应与异常所在例程的接口抽象一致 情况已经发生 在您的案例中,当您说这是一个命名问题时,您显示出朝着正确方向思考的提示。非常接近。。。这是一个抽象问题 所以,
- 如果有人在您的接口级别
工作,并且在SIDReader
中发生异常,则异常应该表示无法从SIDReader读取,并且应该从实现此Open()
接口的实际类中具有InnerException,即SIDReader
或XmlSIDReader
TextSIDReader
- 如果此人在您的
级别工作,并且该类中的XmlSIDReader
中发生异常,则异常消息应表示无法打开Xml文件。。废话废话Open()
- 如果该人员在您的
级别工作,并且该类中的TestSIDReader
中发生异常,则异常消息应表示无法打开文本文件,依此类推Open()
Open()
中调用了其他一些方法,并且异常发生在那里,那么这个方法也应该抛出自己的异常,准确地告诉它的