2014-09-13 64 views
0

假定組分(說COMPA)在SDK暴露出公共C#的.NET類(比如鹼):如何不允許暴露從特定類派生的類?

namespace CompA { public abstract class Base {} } 

一個不同的組件(比如說EXTB)通過從該基類派生延伸COMPA:

namespace ExtB { class Derived : CompA.Base {} } 

您的意見是什麼,請不要允許聲明類ExtB.Derived爲public的最佳方法是什麼? CompA.Base是爲擴展 CompA,但不是爲暴露新的公共API與它。

namespace ExtB { public class Derived : CompA.Base {} } // DISALLOW 

我能想到的是期望程序集暴露公共API被標記爲.NET自定義屬性並用另一個.NET自定義屬性標記基類。加載這些程序集的產品將不允許加載此類程序集,從而暴露/發佈從標有自定義屬性的類型派生的類型。 COMPA的

的AssemblyInfo.cs:

[assembly:SdkApiAssemblyAttribute()] 

的AssemblyInfo.cs EXTB的:

[assembly:SdkApiAssemblyAttribute()] 

Base.cs:

namespace CompA 
{ 
    [Publishable(false)] 
    public abstract class Base {} 
} 

謝謝!

+0

你爲什麼要防止它? – 2014-09-13 15:03:52

+0

@SriramSakthivel,派生類是由ExtB序列化的,所以我想確保它們不會被意外暴露。 – 2014-09-13 15:09:55

+0

@SriramSakthivel,類型Base暴露了ExtB的公共API中沒有必要的信息。當然,暴露此類信息的成員可以在Base類型中聲明爲protected,但我想知道是否可以確保從特定類派生的類不能公開。 – 2014-09-13 15:27:06

回答

0

@SriramSakthivel,你是對的:我做錯了! :)

雖然不是故意我沒有說CompA.Base實際上不是一個類,而是一個接口

public interface Base 
{ 
    string ShouldNotBePublic(); 
} 

的基類應該保護訪問修飾符暴露方法:

public abstract class Base 
{ 
    protected string ShouldNotBePublic(); 
} 

這樣的派生類不會acidentally暴露受保護的信息。組件CompA然後能夠通過實現模板方法模式來訪問此方法:

namespace CompA 
{ 
    public abstract class Base : IBaseInternal 
    { 
     protected string ShouldNotBePublic(); 

     string IBaseInternal.ShouldNotBePublic() 
     { 
      return ShouldNotBePublic(); 
     } 
    } 

    internal interface IBaseInternal 
    { 
     string ShouldNotBePublic(); 
    } 
} 

對不起,我很困惑。

1

起初它聽起來是你做錯了什麼。確認你的意圖只是爲了防止意外暴露,這聽起來很合理。編寫單元測試可能很簡單,但如果派生類不是代碼庫的一部分,則可以執行以下操作。

沒有編譯時間的方法來防止這個(AFAIK)。只需檢查基類構造函數中的類型並拋出異常。

public abstract class Base 
{ 
    protected Base() 
    { 
     if (this.GetType().IsPublic) 
      throw new InvalidOperationException("Type is not meant to be exposed public"); 
    } 
} 

public class Der : Base 
{ 
    public Der() 
    { 

    } 
} 

這將阻止客戶端,如果它被聲明爲public創造Der新實例。

注意:有一些場景,構造函數不會運行,那麼你運氣不好。幸運的是,他們是角落案件,不用擔心太多。例如:FormatterServices.GetUninitializedObject將不會運行該構造函數。

相關問題