2010-03-13 102 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(); 
    } 
}