簡體   English   中英

基類可以確定派生類是否覆蓋了虛擬成員嗎?

[英]Can a base class determine if a derived class has overridden a virtual member?

這是我班級的簡化版本:

public abstract class Task
{
    private static object LockObject = new object();

    protected virtual void UpdateSharedData() { }
    protected virtual void UpdateNonSharedData() { }

    public void Method()
    {
       lock(LockObject)
       {
          UpdateSharedData();
       }
       UpdateNonSharedData();
    }
}

我試圖隱藏派生類的鎖定代碼。 但是如果派生類重寫UpdateSharedData,我只想獲取鎖; 如果沒有,我不希望該方法阻止並等待在更新共享數據之前更新共享數據的所有其他正在運行的實例。

所以對於Method來說(看似)顯而易見的事情是檢查並查看當前實例的UpdateSharedData實現是否覆蓋了基類的實現。 我很確定如果不使用反射這是不可能的,並且可能不希望這樣做。

我已經想到了一些解決方法,但它們都很尷尬:

  • 添加派生類的構造函數設置的受保護bool屬性,並檢查該屬性以查看是否需要鎖定。 這樣做在隱藏派生類中的鎖定代碼方面做得非常糟糕。
  • 使UpdateSharedData方法成為委托屬性,讓任何派生類在其構造函數中將屬性設置為私有方法,並且只有在委托不為空時才獲取鎖。 那更好,但它仍然很糟糕。

如果您定義了一個抽象Task和一個IHasSharedData接口,那么在Method中檢查派生的Task是否在執行鎖之前實現了IHasSharedData。 只有實現接口的類才需要等待。 我意識到這可以避免回答實際問題,但我認為這比使用反射更清晰。 希望你能找到一個更好的界面名稱,它更接近於類的實際功能。

public interface IHasSharedData
{
    void UpdateSharedData();
}

public abstract class Task
{
    private static object LockObject = new object();

    protected virtual void UpdateNonSharedData() { }

    public void Method()
    {
         if (this is IHasSharedData)
         {
            lock(LockObject)
            {
                UpdateSharedData();
            }
         }
         UpdateNonSharedData();
    }
}

public class SharedDataTask : Task, IHasSharedData
{
    public void UpdateSharedData()
    {
       ...
    }
}

你可以用反射的微笑來檢查:

bool IsUpdateSharedDataOverridden()
{
    Type t = this.GetType();
    MethodInfo m = subType.GetMethod("UpdateSharedData");

    return m.DeclaringType == t && m.GetBaseDefinition().DeclaringType == typeof(Task);
}

實際上,你在談論兩個不同的對象:

public abstract class Task {    
    protected virtual void UpdateNonSharedData() { }

    public virtual void Method()    
    {   
        UpdateNonSharedData();    
    }
}

public abstract class TaskWithSharedData : Task {    
    private static object LockObject = new object();    

    protected virtual void UpdateSharedData() { }

    public overrides void Method()    
    {       
        lock(LockObject)
        {          
            UpdateSharedData();       
        }   
        base.Method();
    }
}

但是,更理想的解決方案將是戰略模式。

暫無
暫無

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

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