簡體   English   中英

如何擴展同名方法並被調用?

[英]How to extend a same name method and get called?

我喜歡在類中重寫一個方法,因此我用相同的名稱和參數擴展了該方法,但從未調用過它。

http://msdn.microsoft.com/en-us/library/bb383977.aspx

....與接口或類方法具有相同名稱和簽名的擴展方法將永遠不會被調用。 ....

好吧,我必須接受這一點。

我的問題是:對於未密封的類(甚至我有源代碼),如果我想重寫該類的OUTSide方法(在其他項目中但使用相同的解決方案),該怎么辦?

[編輯]

這是建議的方式,使用虛擬/覆蓋,運行時無錯誤,編譯無錯誤,只是永遠也不會被調用:(,請看一下

在項目A中:

public class CachePlan : ICachePlan
{
    public virtual CacheSettings GetPlan(ControllerContext filterContext)
    {
        return null;
    }
}

在項目B中:

public class CachePlanExtension: CachePlan
{
    public override CacheSettings GetPlan(ControllerContext filterContext)
    {
        CacheSettings ca = new CacheSettings();
        ca.IsCachingEnabled = true;
        ca.Duration = 100;
        return ca;
    }
}

但是從不被調用,CashPlan.GetPlan仍然返回null。 任何想法?

您不能“進入”現有的類並更改其方法的含義。 那將是一個重大的安全漏洞。

簡單的說; “不可能”。 如頁面上所述...

您可以使用擴展方法來擴展類或接口,但不能覆蓋它們。 與接口或類方法具有相同名稱和簽名的擴展方法將永遠不會被調用。 在編譯時,擴展方法的優先級始終比類型本身定義的實例方法低。 換句話說,如果類型具有名為Process(int i)的方法,並且您具有具有相同簽名的擴展方法,則編譯器將始終綁定到實例方法。 當編譯器遇到方法調用時,它首先在類型的實例方法中查找匹配項。 如果找不到匹配項,它將搜索為該類型定義的所有擴展方法,並綁定到找到的第一個擴展方法。

如果您有源代碼,為什么不簡單地從原始類中刪除方法的實現,並在單獨的項目中提供擴展方法

擴展方法只是語法糖,它被編譯為靜態方法調用。 因此,您只可以編寫一個靜態方法來完成相同的事情,就無法完全按照自己的意願來調用它。 如果該方法是虛擬的,則可以在派生類中重寫它。 只要確保您總是實例化自己的類型即可。 您也可以使用new關鍵字,但是將使用簡單的強制轉換和代碼。 最好是為自己創建一個簡單的包裝器類。 該類將具有所討論類的實例,並找出正確的調用。 當創建特殊集合時,這是很常見的,因為許多.NET集合類型不能很好地繼承。 但最糟糕的是,您可以使用Moles

編輯

創建從ActionFilterAttribute繼承的自己的類,並使用該類創建自己的自定義過濾器。

public class MyFilterAttribute : ActionFilterAttribute
{
    public override virtual void OnResultExecuting(ResultExecutingContext filterContext)
    {
        //...
    }
}

不建議在內置屬性中覆蓋它,但是您可以通過多種其他方法來使用該方法。 但是,如果您真的想做,MVC是開源的...

您可以創建這樣的擴展方法(請注意GetPlan()-參數列表中的this-關鍵字):

public class CachePlanExtension //does not have to be static
{
    public static CacheSettings GetPlan(this CachePlan cachePlan, ControllerContext filterContext) //has to be static!
    {
        //the cachePlan-Parameter will later contain the CachePlan-object, on which you call this method. Example:
        var name = cachePlan.Name;


        CacheSettings ca = new CacheSettings();
        ca.IsCachingEnabled = true;
        ca.Duration = 100;
        return ca;
    }
}

只要您可以“看到”擴展類(這意味着它必須是公共的或內部的,並且必須包含擴展類的名稱空間),就可以調用以下方法:

new CachePlan().GetPlan(filterContext);

您可以在繼承的類中重寫該方法。

暫無
暫無

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

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