簡體   English   中英

在虛擬函數中引發異常是否是一種好習慣?

[英]Is it good practice to throw exceptions in virtual functions?

即使解決方案是如此明顯,我也不應該發布過此內容,但我將其作為提醒和參考的參考。

我有以下基類:

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查找什么樣的內容。

所以-我的問題是這樣的:

我是否應該在ObjectInfoFind的基類版本中引發異常,以便如果子類未正確實現,則會出現運行時錯誤? 還是應該為ObjectInfo返回null編寫代碼?

如果需要通過派生類實現方法,為什么不將其抽象而不是虛擬? 這將強制派生類實現成員。 如果他們不希望或無法返回ObjectInfo,則可以選擇自己返回null。

您應將您的基類和要由派生類實現的方法聲明為抽象。 這完全避免了探測,因為編譯器將檢測不覆蓋所有abstarct方法的派生類。

我認為在某些情況下,該屬性是可選的,您應該擁有一個屬性:ObjectInfo和一個布爾“ SupportObjectInfo”。

在這種情況下,您將ObjectInfo屬性標記為虛擬,並拋出NotSupportedException。

您這樣做是因為您的類的使用者可以測試它是否支持該屬性,而不必捕獲錯誤以進行測試。

如果在實現中不是可選的,則應將其標記為抽象。

如果您想“保護”基類的調用者,使其不接收由基類派生的類引發的潛在意外異常,請考慮使用“模板”模式捕獲派生類引發的所有錯誤,並將其轉換為您所認為的異常在基類上定義。 您還應該考慮將派生類拋出的異常作為內部異常傳遞。

您當然可以這樣做,但是異常通常表示執行時錯誤,而不是實現錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM