[英]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.