C# 在C中的另一个类内声明的类#
我正在编写一些遗留代码,遇到了一些我不确定的东西。我们有一个C# 在C中的另一个类内声明的类#,c#,oop,class,C#,Oop,Class,我正在编写一些遗留代码,遇到了一些我不确定的东西。我们有一个类y,它在另一个类x中声明类y仅在类x中使用,但我的问题是,为什么不创建一个单独的类文件并将类y放在其中,而不是在类x中声明它?这是不是违反了OOP,或者只是一个风格问题,因为它只在这个类中使用过。我正在重构一些代码,我的第一反应是将类y分离到它自己的文件中。 namespace Library { public class x { // methods, properties, local members of
类y
,它在另一个类x
中声明<代码>类y仅在类x
中使用,但我的问题是,为什么不创建一个单独的类文件并将类y
放在其中,而不是在类x
中声明它?这是不是违反了OOP,或者只是一个风格问题,因为它只在这个类中使用过。我正在重构一些代码,我的第一反应是将类y
分离到它自己的文件中。namespace Library
{
public class x
{
// methods, properties, local members of class x
class y
{
// methods, properties, local members of class y
}
}
}
创建内部类是因为它只在类x的范围内使用,并且在逻辑上符合类x的分解/体系结构
类y可能还知道不为公众所知的类x的实现细节。这有权限含义。顶级的“y类”是“内部的”——然而,这里的“y”是“x”的私有的。这种方法有助于实现细节(例如缓存行等)。同样,
y
可以访问x
的所有私有状态
泛型也有其含义x.y
是从外部类继承的通用“of 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; }
}
}
class-Foo{
孔隙试验(T值){
条形=新条形();
bar.Value=Value;
}
分类栏{
公共T值{get;set;}
}
}
人们常常错误地认为他们需要将
条形码定义为条形码>-这现在(实际上)是双重通用的-即Foo
-其中告诉是Foo
中的T
。所以不要那样做!或者,如果您希望它具有双重通用性,请选择不同的名称。幸运的是,编译器警告您这一点…我认为这没关系,只要包含的类仅用作实用工具。例如,我使用这种构造来为私有方法定义复杂的返回类型。我只是浏览了我正在更新(以及我最初编写的)的代码,并删除了所有嵌套类。不幸的是,我最初使用的嵌套类不在它所定义的类中。将嵌套类移出对我来说意义重大,因为我最初的设计很糟糕
如果Y只在X中使用,并且永远不会在X之外使用,我会说将其保留在那里这段代码很好,因为您给出了确切的原因——“Y类只在X类内部使用”。这些都是,使用它们的指导原则之一是嵌套类型应该与其声明类型紧密耦合,并且不能用作通用类型。这样,嵌套类对其他类来说是不可访问的,但仍然允许您遵循面向对象的原则。让我给您一个使用嵌套类的示例,以说明这种体系结构何时合适。我最近需要通过从数据表中提取选定的列并“旋转”它们来生成一个HTML表,从而使行变成列,反之亦然。在我的例子中,有两个基本操作:数据透视和生成一些相当复杂的输出(我不仅仅是显示数据:每个数据列/表行都要执行提取标题、生成图像标记、设置链接等操作。因此,使用SQL透视也不太正确)
在最初尝试创建一个类来完成整个任务后,我发现大部分数据/方法分为三个不同的分区:标题处理、行处理和数据透视。因此,我决定更好的方法是将“header”和“row”的逻辑封装到单独的嵌套类中。这使我能够分离每一行持有的数据,并非常干净地编程透视操作(为数据表中的每一列调用单独的行对象)。在pivot操作结束时,我通过调用header对象生成输出,然后依次调用每个row对象生成其返回到主类的输出
单独的类不合适,因为A)嵌套类确实需要来自主类的一些数据,B)处理非常具体,在其他地方没有用处。仅仅编程一个大类就更混乱了,因为围绕“列”和“行”等术语的混淆取决于您谈论的是数据还是HTML输出。另外,这是一项不同寻常的工作,因为我在业务类中生成HTML,所以我想将纯业务逻辑从UI生成中分离出来。最后,嵌套类提供了封装和数据共享的完美平衡 您仍然可以将类y重构到另一个文件中,但是使用一个对等类。这样做的好处是,每个文件仍然有一个类,并且没有将声明移到类x之外的重构麻烦
e、 你可以有一个代码文件:x.y.cs,它看起来像
partial class X
{
class Y
{
//implementation goes here
}
}
+1解释来自外部类的“T”如何成为内部类的封闭构造类型的一部分可能是一个好主意。这是很多人都不知道的一个重要问题。在定义Test()
之前,是否需要向前声明Bar
?这是真的吗?根据我的测试,Y类无法访问X类的详细信息。这怎么可能?没关系,刚刚找到