2010-03-13 183 views
8

最近我一直在做一些編程,遇到了一個我在c#中發現奇怪的問題。 (至少對我來說)隱藏的構造函數在c#中不可能嵌套類?

public class Foo 
{ 
    //whatever 
    public class FooSpecificCollection : IList<Bar> 
    { 
     //implementation details 
    } 
    public FooSpecificCollection GetFoosStuff() 
    { 
     //return the collection 
    } 
} 

我想富的消費者能夠獲得到FooSpecificCollection參考,甚至在其上執行某些操作。也許甚至可以將它設置爲Foo的其他屬性,或者像這樣,但不能創建此類的實例。 (應該能夠安裝這個集合的唯一的類應該是Foo)

我的請求真的太牽強了嗎?我知道人們的方式更聰明的定義了c#但不應該有這樣的選項,父類可到目前爲止,創建一個嵌套類實例,但其他人卻不能。

我創建了一個解決方案,使一個抽象類,或提供接口,通過物業和實施具體的私有類,是不是其他任何地方。

這是處理這種情況的正確方法嗎?

+0

可能重複:http://stackoverflow.com/questions/1664793/how-to-restrict-access-to-nested-class-member-to-enclosing-class – 2010-03-14 02:34:38

+0

好奇:是否會有'Foo的多個實例,每個實例都有自己獨特的'FooSpecificCollection'? – BillW 2010-03-14 09:23:25

+0

是的,就是這樣。假設每個客戶端都有一個Foo實例(它將在某個精確時間由工廠創建),Foo將爲其自身創建一個FooSpecificCollection。我可以訪問foo特定的集合,以便讓人們知道foo具有什麼內容,我讓它們玩這些項目,但是它們不應該能夠創建一個,因爲它沒什麼意義。在晚上,我想也許我儘量讓這個代碼太多的語義:) – luckyluke 2010-03-14 09:41:01

回答

4

嵌入類的工作方式是,它們作爲外部類的成員可以訪問該外部類的私有成員。但不是相反(你想要什麼)。

您可以屏蔽FooSpecificCollection的構造函數,但Factory必須是FooSpecificCollection本身的一部分。它可以爭取外部類:

public class Foo 
{ 
    public class FooSpecificCollection : List<Bar> 
    { 
     private FooSpecificCollection() { } 

     public static FooSpecificCollection GetFoosStuff() 
     { 
      var collection = new FooSpecificCollection(); 
      PrepareFooSpecificCollection(collection); 
      return collection;    
     } 
    } 

    private static void PrepareFooSpecificCollection(FooSpecificCollection collection) 
    { 
     //prepare the collection 
    } 
} 
+0

可能你是對的:)它很像工廠模式(我真的想過它)。 – luckyluke 2010-03-13 22:29:35

+0

總是從你的答案中學到一些東西,謝謝Henk。在這種情況下,如果有多個「Foo」實例會發生什麼? – BillW 2010-03-14 09:25:03

+1

@BillW,如果你真的是使用這種模式,你可能會不得不通過GetFooStuff()和上PrepareFooSpecificCollection()來傳遞美孚的一個實例。 – 2010-03-14 09:47:04

3

如果您是cre在圖書館供他人使用,你可以使構造函數internal。圖書館外的任何人都無法訪問它。如果您擔心在您自己的項目中調用構造函數,請不要在父類之外調用它。

我們一直創建與其他類沒有直接關係的類,但構造函數不必從非相關類中隱藏。我們(程序員)知道這些對象是不相關的,所以我們不會在另一個對象中創建一個實例。

0

不,並沒有什麼意義。

我的意思是整個點是這樣,你可能會返回其他實例;但是誰又會從這個類別中派生出來呢?當然不是任何其他類(因爲那將是錯誤的,並暗示它應該不是主要的類中被隱藏),所以...

+0

我想在嵌套類中的一些功能,簡潔明瞭閱讀和使用(對FOO的一些內部集合前漂亮的界面)。 我不想讓人們創造這個類。當然,他們應該沒有這方面的業務,但我仍然希望有一個清晰的語義 - 這個類可以幫助你操作一些Foo的東西,但是Foo也會給你,你不應該單獨創建它... 內部處於組裝 好,但我不明白你的答案,爲什麼它沒有SENS。我想要一個使用我的類的開發人員不要嘗試實例化它...爲什麼沒有意義? – luckyluke 2010-03-13 22:14:12

+0

這裏還有其他一些問題,而不是派生類。 – 2010-03-13 22:17:28

+0

luckyluke:那麼使構造函數是私人的?我以爲你試圖阻止外面的階級製造一個實例。 – 2010-03-13 23:23:56

4

讓您的嵌套類private做出的GetFoosStuffIList<Bar>的返回值,而不是FooSpecificCollection

此外,還有一個很好的機會deriving from List<Bar> is a bug

+0

我從列表中派生不是foo – luckyluke 2010-03-13 22:15:16

+0

對不起我的意思當然IList中。列表將是內部實現。但這不是問題所在。 但感謝警惕:) – luckyluke 2010-03-13 22:16:23

+1

只是好奇,你的意思是「從'名單'推導是一個錯誤」。我查看了鏈接,但是本身並沒有發現任何可以從'List '派生出來的問題。當你聲稱一些時間 – 2010-03-13 22:17:21

1

有一種解決方案,但我不認爲我會在我的應用程序中使用它:) 這個想法是從FooSpecific派生的類,它是私有的,只能在Foo中使用,但具有公共構造函數,所以Foo可以創建它的實例。

public class Foo 
{ 
    //whatever 
    public class FooSpecific 
    { 
     // Protected contructor. 
     protected FooSpecific() 
     { 
     } 

     // All other code in here. 
    } 

    // Private helper class used for initialization. 
    private class FooSpecificInitHelper : FooSpecific 
    { 
     public FooSpecificInitHelper() 
     { 
     } 
    } 

    // Method in foo to create instaces of FooSpecific. 
    private FooSpecific CreateFooSpecific() 
    { 
     return new FooSpecificInitHelper(); 
    } 
}