在C#中的另一个类内声明的类

时间:2009-03-26 12:48:38

标签: c# oop class

我正在研究一些遗留代码,并且遇到了一些我不确定的问题。我们在另一个class y内声明了class xClass y只在class x内使用,但我的问题是为什么不创建单独的类文件并将class y放在其中而不是在class x内声明它?这不是违反OOP的,或者只是风格问题,因为它只在本课程中使用过。我正在重构一些代码,我的第一反应是将class y分成它自己的文件。

namespace Library
{
   public class x
   {
      // methods, properties, local members of class x

      class y
      {
         // methods, properties, local members of class y
      }
   }
}

7 个答案:

答案 0 :(得分:59)

您创建了一个内部类,因为它只在类x的范围内使用,并且它在逻辑上适合于类x的因子/体系结构。

类y也可能知道x类的实现细节,这些细节并不是公众所知。

答案 1 :(得分:20)

这具有权限含义。顶级“类y”将是“内部” - 但是,这里“y”对“x”是私有的。此方法有助于实现细节(例如缓存行等)。同样,y可以访问x的所有私有状态。

对仿制药也有影响; x<T>.y是通用的“T”,继承自外部类。您可以在此处看到此处,Bar充分利用T - 并注意Bar的所有静态字段的范围均为T

class Foo<T> {
    void Test(T value) {
        Bar bar = new Bar();
        bar.Value = value;
    }
    class Bar {
        public T Value { get; set; }
    }
}

通常人们错误地认为他们需要将Bar定义为Bar<T> - 现在(实际上)双重泛型 - 即Foo<TOld, T> - 其中{{1}来自TOld的(现在不可用)T。所以不要这样做!或者,如果您想要它是双重通用的,请选择不同的名称。幸运的是,编译器会警告你......

答案 2 :(得分:7)

这个代码很好,因为你给出的确切原因 - “类y只在类x中使用过”。那些是nested types,并且使用它们的指导之一是嵌套类型应该与它们的声明类型紧密耦合,并且不能用作通用类型。这样,嵌套类对其他类来说是不可能的,但仍然允许你遵循面向对象的原则。

答案 3 :(得分:2)

我认为没关系,只要包含的类仅用作实用程序。我使用这种结构来定义私有方法的复杂返回类型。

答案 4 :(得分:2)

我刚刚浏览了我正在更新的代码(我最初写的)并删除了所有嵌套类。不幸的是,我最初在它定义的类之外使用了嵌套类。移动嵌套类对我来说有很大的不同,因为我最初设计不好。

如果Y仅在X中使用并且永远不会在X之外使用,我会说保持在那里

答案 5 :(得分:2)

让我举一个使用嵌套类的例子,这些嵌套类可能会澄清何时这种架构是合适的。我最近需要通过从数据表中提取所选列并“旋转”它们来生成HTML表,以便行成为列,反之亦然。在我的例子中,有两个基本操作:转动数据并生成一些相当复杂的输出(我不只是显示数据:每个数据列/表行都受制于提取标题,生成图像标签,设置链接的操作,因此,使用SQL Pivot也不是正确的。)

在最初尝试创建一个类来执行整个操作之后,我意识到许多数据/方法分为三个不同的分区:头处理,行处理和旋转。因此,我认为更好的方法是将“header”和“row”的逻辑封装到单独的嵌套类中。这允许我将每行保存的数据分开,并非常干净地编程数据透视操作(为数据表中的每一列调用一个单独的行对象)。在数据透视操作结束时,我通过调用头对象生成输出,然后依次将每个行对象生成回主类的输出。

单独的类是不合适的,因为A)嵌套类确实需要来自主类的一些数据,B)处理非常具体,在其他地方没用。由于围绕“列”和“行”之类的术语混淆,根据您是在谈论数据还是HTML输出,编写一个大类只是简单的混乱。此外,这是不寻常的工作,因为我在我的业务类中生成HTML,所以我想从UI生成中分离出纯粹的业务逻辑。最后,嵌套类提供了封装和数据共享的完美平衡。

答案 6 :(得分:1)

你仍然可以将你的类y重构为另一个文件,但是使用一个parial类。这样做的好处是每个文件仍然有一个类,并且没有在x类之外移动声明的重构麻烦。

e.g。你可以有一个代码文件:x.y.cs看起来像

partial class X
{
    class Y
    {
        //implementation goes here
    }
}