2008-10-13 86 views
9

我想在System.Web.Script.Services.ScriptHandlerFactory和其他.NET內部類中定製一些東西。不幸的是,這是一個內部課程。在嘗試自定義此類中的方法時,我有什麼選擇?如何「重寫」C#中的內部類?

+0

你真的不應該因爲類的所有者將其標記爲內部(讀..不延長,因爲我可能會改變它後來/它正在進行中/不是最好的)。如果你真的必須創建你自己的課程副本並使用它。 – Gishu 2008-10-13 06:11:08

回答

6

您可能會感興趣this recent article的啓發。基本上,它表示你不能覆蓋任何標記爲internal的東西,並且源代碼就像它獲得的權威一樣。最好你可以希望是一種擴展方法。

+0

Eric Lippert的博客是一個很好的資源,我已經跟蹤了好幾年。 – Kev 2008-10-13 02:46:35

5

內部關鍵字表示代碼單元(類,方法等)對其所在的程序集「公開」,但對任何其他程序集都是私有的。

因爲你不在同一個集會,你什麼都做不了。如果它不是內部的,則可以在擴展類時在覆蓋的方法上使用新的關鍵字(隱藏原始實現)。

總之:你將成爲SOL。

我能想到的唯一辦法就是寫一個代理類,其中一個私有字段是您想要擴展的類,然後實現它的所有方法並代理它們的調用。這樣你仍然可以自定義輸出,但是你必須讓你的課程得到使用,並且考慮到它的內部標記,我不確定沒有嚴重的黑客攻擊是可能的。

using System; 
... 
using System.Web.Script.Services 

namespace MyGreatCompany.ScriptServices 
{ 
    public class MyScriptHandlerFactory /* implement all the interfaces */ 
    { 
     private ScriptHandlerFactory internalFactory; 
     public MyScriptHandlerFactory() 
     { 
      internalFactory = new ScriptHandlerFactory(); 
     } 
     ... 
    } 
} 

可能讓你想完成什麼可能的,但它不會是漂亮。

1

我相信你可以使用反射來解決一類的訪問修飾符,所以也許你可以使用Reflection.Emit的生成,從一個內部類繼承的類型(但不 sealed修飾符),雖然我找不到這個在線的例子。

這當然適用於訪問類的私有成員,也可能用於繼承非密封類。但是,如果目標方法不是已經標記爲虛擬的,那麼它沒有多大幫助。

+0

它也可能只在完全信任的情況下運行。當您違反訪問控制時,任何需要驗證的上下文都會失敗。 – 2008-10-13 05:23:19

0

這取決於組裝。這可能違反可能有些牌(儘管它類似於某種靜態連接的),甚至可能使部署的噩夢,但你可以考慮:

  • 和反編譯的代碼到自己的項目複製;根據需要
  • 重新編譯/貼片組裝,並添加一個「InternalsVisibleToAttribute」修改