在虚函数中抛出异常是否是一种好的做法?
即使解决方案如此明显,我应该从未发布过这个消息,我将其作为提醒和对其他人的参考。在虚函数中抛出异常是否是一种好的做法?
我有以下基本类:
using System;
namespace LibraryWPF
{
public class Library
{
/// <summary>
/// Event fired when content is added to the libary
/// </summary>
public event EventHandler<ObjectInfoEventArgs> Library_ObjectAdded;
/// <summary>
/// Event fired when the scan of the library is finished
/// </summary>
public event EventHandler Library_Finished;
// Properties
/// <summary>
/// Whether to stop checking the library or not
/// </summary>
public bool Stop
{
get;
set;
}
/// <summary>
/// Where to look for content
/// </summary>
public string Root
{
get;
set;
}
/// <summary>
/// Empty instance of library's object for reflection
/// </summary>
public virtual object ObjectInfo
{
get
{
// Should this raise as exception to show if it's not been overridden?
return null;
}
}
/// <summary>
/// Sub class overrides this method to call it's actual find code
/// </summary>
public virtual void Find()
{
// Should this raise as exception to show if it's not been overridden?
}
/// <summary>
/// Build the library
/// </summary>
public void Build()
{
if (Root != null && Root.Length > 0)
{
Stop = false;
Find();
}
// Final update
if (Library_Finished != null)
{
Library_Finished(this, null);
}
}
/// <summary>
/// Sub class calls this method to fire the ObjectAdded event
/// </summary>
/// <param name="objectInfo">Object just added to library</param>
protected void OnObjectAdded(object objectInfo)
{
if (Library_ObjectAdded != null)
{
Library_ObjectAdded(this, new ObjectInfoEventArgs(objectInfo));
}
}
}
}
子类覆盖ObjectInfo
返回对象,他们正在寻找通过使用反射型的实例。他们也覆盖Find
做实际的搜索。
这样我的应用程序代码就可以使用基类方法,因此在编译时它不需要知道有关子类的任何信息。我告诉它使用DI寻找什么样的内容。
所以 - 我的问题是这样的:
我应该抛出一个异常在ObjectInfo
基类版本和Find
因此,如果子类不正确执行我得到一个运行时错误?或者我应该编码ObjectInfo
返回null
?
如果你需要一个方法由派生类实现,为什么不使用抽象而不是虚拟?这将强制派生类实现该成员。如果他们不想或者不能返回一个ObjectInfo,他们可以选择自己返回null。
+1使方法抽象化。 – 2009-04-27 13:52:03
谢谢 - 这就是我想到的,但不记得这个词 - 为什么我不知道:) – ChrisF 2009-04-27 14:21:42
你当然可以这样做,但异常通常表示执行时错误,而不是执行错误。
你应该声明你的基类和被派生类实现的方法是抽象的。这完全避免了探针,因为编译器会检测不覆盖所有abstarct方法的派生类。
我认为有些情况下属性是可选的,你应该有一个属性:ObjectInfo和一个布尔“SupportObjectInfo”。
在这种情况下,您将ObjectInfo属性标记为虚拟并抛出NotSupportedException。
你这样做是因为你的类的消费者可以测试它是否支持该属性,并且不需要为测试捕获错误。
如果在实现中不是可选的,则应将其标记为抽象。
如果您想“保护”基类的调用者接收从您的基类派生的类抛出的潜在意外异常,请考虑使用模板模式来捕获派生类抛出的任何错误,并将它们转换为您在基类中定义的异常。您还应该考虑将派生类抛出的异常作为内部异常传递。
我不能相信我完全忘了让方法抽象化。 – ChrisF 2009-04-27 14:50:23