2012-09-19 52 views
6

我有一個類庫,有2個公共類,它們繼承自一個抽象類。在抽象類中,我有一個只能被繼承類訪問的​​受保護字段。該字段使用的類型是內部類的類型。使用內部類型作爲保護字段

比如我有:

internal class MyInternalClass 
{ 
    ... 
} 

public abstract class MyAbstractClass 
{ 
    protected MyInternalClass myField; 
} 

現在我明白了,如果從MyAbstract類派生類的一個擴展的組件之外,這將不是因爲工作,訪問MyField的將是非法的。

我的問題是我如何讓事情工作,同時保持MyInternalClass內部(它不應該在程序集外部訪問)並允許程序集內的類通過訪問myField來擴展MyAbstractClass?

+4

後者('abstract')類必須是「公共」嗎? –

+0

是的,它一定是。擴展它的兩個類是公共的。 – zaq

+0

[如何在C#中保護屬性和內部?](http:// stackoverflow。com/questions/941104/how-to-make-a-property-protected-and-internal-in-c) – nawfal

回答

5

創建一個公共接口MyAbstractClass要求和MyInternalClass實現。

像這樣的東西,所以你可以擁有它是MyInternalClass默認,但如果你需要注入新的行爲(例如,嘲諷):

internal class MyInternalClass : IMyInterface 
{ 
} 

public interface IMyInterface 
{    
} 

public abstract class MyAbstractClass 
{ 
    protected IMyInterface myField; 

    protected MyAbstractClass(IMyInterface required = null) 
    { 
     myField = required ?? new MyInternalClass(); 
    } 
} 
+2

您也可以將內部類引用存儲在專用字段中,然後提供一個受保護的屬性,將其公開爲公共接口。這有一個副作用,允許您進一步限制對內部類(通過接口)的訪問,以僅限MyAbstractClass中的派生類所需的內容。它也爲你提供了靈活性,如果這個接口的實現方式不同(例如將其功能分解爲兩個輔助類而不是一個)。 –

+0

@DanBryant:非常真實。好建議。 –

0

你不能。如果MyAbstractClass來源於外部類別MyInternalClass需要知道。

如果您需要考慮這樣的事情,設計可能需要返工。

0

使該字段myFieldinternal protected

您還必須製作MyAbstractClass內部。如果它從一個內部類繼承,它是無法公開的。如果該類必須是公共的,那麼必須有一種方法來解決它:例如,創建一個接口,該接口公開繼承類所需的功能MyInternalClass

0

您需要指定保護的關鍵字「和」內部而不是保護「或」內部。這樣的關鍵字不存在(從C#5.0開始)。他們可以在更高版本中添加它。

這裏有很多線程在這裏。 Se例如question 5596338

此外:現在我已經想出這個「解決方案」:

public abstract class MyAbstractClass 
{ 
    protected class AccessMyFieldHelper 
    { 
     internal MyInternalClass this[MyAbstractClass mac] 
     { 
      get { return mac.myField; } 
      set { mac.myField = value; } 
     } 
    } 
    protected static readonly AccessMyFieldHelper AccessMyField = new AccessMyFieldHelper(); 

    private MyInternalClass myField; 
} 

myField現在是private,但通過AccessMyField保護的訪問。因爲它是一個索引器,所以你將不得不使用方括號[]

您認爲如何?這可以做得更漂亮嗎?