在虚函数中抛出异常是否是一种好的做法?

在虚函数中抛出异常是否是一种好的做法?

问题描述:

即使解决方案如此明显,我应该从未发布过这个消息,我将其作为提醒和对其他人的参考。在虚函数中抛出异常是否是一种好的做法?

我有以下基本类:

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

+0

我不能相信我完全忘了让方法抽象化。 – ChrisF 2009-04-27 14:50:23

如果你需要一个方法由派生类实现,为什么不使用抽象而不是虚拟?这将强制派生类实现该成员。如果他们不想或者不能返回一个ObjectInfo,他们可以选择自己返回null。

+1

+1使方法抽象化。 – 2009-04-27 13:52:03

+1

谢谢 - 这就是我想到的,但不记得这个词 - 为什么我不知道:) – ChrisF 2009-04-27 14:21:42

你当然可以这样做,但异常通常表示执行时错误,而不是执行错误。

你应该声明你的基类和被派生类实现的方法是抽象的。这完全避免了探针,因为编译器会检测不覆盖所有abstarct方法的派生类。

我认为有些情况下属性是可选的,你应该有一个属性:ObjectInfo和一个布尔“SupportObjectInfo”。

在这种情况下,您将ObjectInfo属性标记为虚拟并抛出NotSupportedException。

你这样做是因为你的类的消费者可以测试它是否支持该属性,并且不需要为测试捕获错误。

如果在实现中不是可选的,则应将其标记为抽象。

如果您想“保护”基类的调用者接收从您的基类派生的类抛出的潜在意外异常,请考虑使用模板模式来捕获派生类抛出的任何错误,并将它们转换为您在基类中定义的异常。您还应该考虑将派生类抛出的异常作为内部异常传递。