在C#和C ++中使用嵌套类 - 为什么以及何时?

时间:2013-03-03 20:08:00

标签: c# c++

在我的自我导向努力将我的编程技巧和习惯带入21世纪(从Pascal& Fortran迁移到C#和C ++),我一直在研究相当数量的可用源代码。就我能够确定而言,课程是独一无二的“独立”课程。实体(很像它们的功能祖先)。

但是,我遇到了许多实例,其中一个或多个类嵌套在另一个类中。我的直觉本能'在这方面,这样做只是由于极差的方法论 - 然而,我还不熟悉现代的OOP方法来真正做出这样的决定。

因此,以下重叠的问题:

是否有合理的理由将一个类嵌套在另一个类中?而且,如果是这样,那么这样做的理由是什么,而不是每个阶级完全独立?

(注意:我见过的例子一直在使用C#,但似乎这个方面同样适用于C ++。)

4 个答案:

答案 0 :(得分:3)

这可能需要一个非常具有启发性的答案,因此许多人不同意我的回答。我是那些认为没有真正需要嵌套课程的人之一,我倾向于同意你的陈述:

  
    

我在这方面的“直觉”是,这样做仅仅是因为方法极差

  

人们认为需要设计嵌套类的情况是与外部类中设计的行为紧密耦合的功能。例如。事件处理可以在内部类中设计,或者Threading行为可以找到内部类的方法。

我宁愿重构“外部”类中的特定行为,以便最终得到两个较小的类,它们都有明确的职责。

对我来说,设计内部类的主要缺点是它们倾向于混淆功能,这些功能很难(呃)与主体一起使用TDD(测试驱动开发)。

如果您不依赖于测试驱动的校长,我认为这不会对您造成太大伤害。它(像许多事情一样)是一种品味问题,而不是对与错的问题。我了解到这个话题可能导致长时间的讨论。非常类似于你是否应该使用static辅助类,这些辅助类往往不仅仅是“成为帮助者”而且随着时间的推移越来越多。

如果你碰到现实生活中的例子,讨论会变得更加具体。在那之前,它将主要是人们的“直觉”。

答案 1 :(得分:1)

C#中嵌套类的常见用法包括您的类内部使用的类,这些类不希望在模块的内部命名空间中公开。例如,您可能需要抛出一个不暴露给外部世界的异常。在这种情况下,您可能希望将其设置为嵌套类,以便其他人无法使用它。

另一个例子是二叉树的Node类。它不仅是您不希望在课堂外暴露的东西,而且可能需要访问私人成员进行内部操作。

答案 2 :(得分:0)

您经常遇到嵌套类的一个区域(尽管可能没有注意到)是枚举器(即实现IEnumerator<T>的类)。

为了使集合支持多个同时枚举(例如,在同一集合中的多个线程,甚至只是嵌套的foreach循环),枚举逻辑需要从集合中分离到另一个类中。 / p>

但是,为了正常工作,枚举器通常需要具体了解集合的实现细节。如果你用一个完全独立的(非嵌套的)类来做这个,你必须使这些内部更容易访问,从而打破封装。 (或许可以说它可以使用internal成员完成,但我认为这仍然在某种程度上打破了封装,即使它“仅”将实现细节暴露给同一程序集的成员)。

通过为枚举器使用私有嵌套类,这些问题在保持适当封装的同时消失了,因为嵌套类可以访问其包含类的内部。

答案 3 :(得分:0)

嵌套类有利有弊。专业人员围绕故意使用,例如Iridium提到的IEnumerator<T>和嵌套类,以促进Command Pattern中的WPF/MVVM。 SQL创建,读取,更新和删除(CRUD)操作很常见,可以使用这些模式封装在代码中的类/命令中,用于业务线/数据驱动的应用程序。

与嵌套类相关的否定与调试相关 - 嵌套的类越多,复杂性越大,引入错误就越容易,调试它就越困难。即使使用类似命令模式的东西,也可以使用太多的类/命令来扩展你的类。