【问题标题】:Class declared inside of another class in C#在 C# 中的另一个类中声明的类
【发布时间】:2010-10-15 16:45:16
【问题描述】:

我正在处理一些遗留代码,但遇到了一些我不确定的事情。我们有一个class y,它在另一个class x 中声明。 Class 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
      }
   }
}

【问题讨论】:

    标签: c# oop class


    【解决方案1】:

    您创建了一个内部类,因为它只在 x 类的范围内使用,并且在逻辑上适合 x 类的分解/架构。

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

    【讨论】:

    【解决方案2】:

    这具有权限含义。顶级“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&lt;T&gt; - 现在(实际上)双重 通用 - 即Foo&lt;TOld, T&gt; - 其中TOld 是(现在不可用) T 来自 Foo&lt;T&gt;。所以不要那样做!或者,如果您希望它具有双重通用性,请选择不同的名称。幸运的是,编译器会就此发出警告...

    【讨论】:

    • +1 解释一下外部类中的“T”如何成为内部类的封闭构造类型的一部分可能是个好主意。这是许多人没有意识到的重要一点。
    • Test()的定义中使用之前需要转发声明Bar吗?
    【解决方案3】:

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

    例如你可以有一个代码文件:x.y.cs,看起来像

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

    【讨论】:

      【解决方案4】:

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

      在最初尝试创建一个类来完成整个事情之后,我意识到大部分数据/方法分为三个不同的部分:标题处理、行处理和数据透视。因此,我决定更好的方法是将“标题”和“行”的逻辑封装到单独的嵌套类中。这使我能够分离每一行保存的数据并非常干净地对数据透视操作进行编程(为数据表中的每一列调用单独的行对象)。在枢轴操作结束时,我通过调用表头对象生成输出,然后依次调用每个行对象将其输出返回给主类。

      单独的类不合适,因为 A) 嵌套类确实需要来自主类的一些数据,并且 B) 处理非常具体,在其他地方没有用处。由于诸如“列”和“行”之类的术语会因您谈论的是数据还是 HTML 输出而有所不同,因此仅仅对一个大类进行编程就会变得更加混乱。此外,这是一项不寻常的工作,因为我在业务类中生成 HTML,因此我想将纯业务逻辑与 UI 生成分开。最后,嵌套类提供了封装和数据共享的完美平衡。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

          由于您给出的确切原因,此代码很好 - “类 y 仅在类 x 内使用”。这些是nested types,使用它们的准则之一是嵌套类型应该与其声明类型紧密耦合,并且不能用作通用类型。这样嵌套类就无法访问其他类,但仍然允许您遵循面向对象的原则。

          【讨论】:

            【解决方案7】:

            我刚刚浏览了我正在更新(并且是我最初编写的)的代码并删除了所有嵌套类。不幸的是,我最初在定义它的类之外使用了嵌套类。将嵌套类移出对我产生了巨大的影响,因为我最初的设计很糟糕。

            如果 Y 只用于 X 并且永远不会在 X 之外使用,我会说保留它

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-01-12
              • 1970-01-01
              相关资源
              最近更新 更多