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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/685629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 13:24:21  来源:igfitidea点击:

Class declared inside of another class in C#

c#oopclass

提问by Jeremy Cron

I am working on some legacy code and have come across something that I'm not sure of. We have a class ythat is declared inside of another class x. Class yis only ever used inside of class xbut my question is why wouldn't you create a separate class file and put class yin there instead of declaring it inside of class x? Isn't this violating OOP's or is it just a matter of style since it is only ever used inside of this class. I'm refactoring some of this code and my first reaction would be to separate class yout into it's own file.

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

采纳答案by plinth

You create an inner class because it is only ever used within the scope of class x and it logically fits in the factoring/architecture of class x.

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

Class y might also be privy to implementation details of class x that are not meant to be known to the public.

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

回答by Marc Gravell

This has permissions implications. A top-level "class y" would be "internal" - however, here "y" is private to "x". This approach is helpful for implementation details (for example cache rows etc). Likewise, yhas access to all private state of x.

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

There are also implications with generics; x<T>.yis generic "of T", inherited from the outer class. You can see this here, where Barhas full use of T- and note that any static fields of Barare scoped per-T.

泛型也有影响;x<T>.y是通用的“T”,继承自外部类。您可以在此处看到这一点,其中Bar充分使用了T- 并注意,任何静态字段的Bar范围都是 per- T

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

Often people incorrectly think they need to define Baras Bar<T>- this is now (effectively) doublygeneric - i.e. Foo<TOld, T>- where TOldis the (now unavailable) Tfrom Foo<T>. So don't do that! Or if you wantit to be doubly-generic, pick different names. Fortunately, the compiler warns you about this...

通常人们错误地认为他们需要定义BarBar<T>- 这现在(实际上)是双重通用的 - 即Foo<TOld, T>- TOld(现在不可用)T来自Foo<T>. 所以不要那样做!或者,如果您希望它具有双重通用性,请选择不同的名称。幸运的是,编译器会警告你这个......

回答by phatoni

I think it's ok, as long as the contained class is only used as utility. I use this sort of construct for example to define complex return types for private methods.

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

回答by Dan McClain

I just went through code that I am updating (and I originally wrote) and removed all nested classes. Unfortunately, I originally used the nested class outside of the class it was defined in. Moving nested classes out made a huge difference to me because I originally had bad design.

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

If Y is only used in X and will never be used outside of X, I'd say keep it there

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

回答by Pawel Krakowiak

This code is fine for the exact reason that you have given - "class y is only ever used inside of class x". Those are nested typesand one of the guidelines for using them is that nested types should be tightly coupled to their declaring type and must not be useful as a general purpose type. That way the nested class is inacessible to other classes, but still allows you to follow object oriented principles.

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

回答by Mark Brittingham

Let me give you an example of the use of nested classes that might clarify when this kind of architecture is appropriate. I recently needed to generate an HTML table by pulling selected columns from a data table and "pivoting" them so that rows become columns and vice versa. In my case, there were two essential operations: pivoting the data and generating some rather complex output (I was not just showing the data: each data column/table row was subject to operations for extracting title, generating image tags, setting up links, etc. thus using a SQL Pivot wasn't really right either).

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

After an initial attempt to create one class to do the whole thing, I recognized that much of the data/methods fell into three distinct partitions: header processing, row processing, and pivoting. Thus, I decided that a better approach would be to encapsulate the logic for "header" and "row" into separate, nested classes. This allowed me to separate the data held by each row and program the pivot operations very cleanly (calling a separate row object for each column in your data table). At the end of the pivot operations, I generated output by calling the header object and then each row object in turn to generate its output back to the main class.

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

Separate classes weren't appropriate because A) the nested classes did need some data from the master class and B) the processing was very specific and not useful elsewhere. Just programming one big class was simply messier due to confusion surrounding terms such as "column" and "row" which differed depending on whether you were talking about data or HTML output. Also, this was unusual work in that I was generating HTML in my business class so I wanted to pull apart the pure business logic from the UI generation. In the end, nested classes provided the perfect balance, then, of encapsulation and data sharing.

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

回答by Matthew Dresser

You could still refactor your class y into another file, but use a parial class. The benefit of this is that you still have one class per file and don't have the refactoring hassles of moving the declaration outside of class x.

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

e.g. you could have a code file: x.y.cs which would look something like

例如,你可以有一个代码文件:xycs,它看起来像

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