6

C# 中是否有类似于您在 C++ 中找到的类定义和实现的概念?

我更喜欢通过删除大多数(如果不是全部)实现细节来保持我的类定义简单(这取决于您可能知道的几个因素,但通常我倾向于将大多数成员实现细节留在类定义之外)。这样做的好处是让我可以鸟瞰类及其功能。

但是在 C# 中,我似乎被迫在声明时定义我的成员函数。这可以避免,还是以某种方式规避?

在我学 C# 期间,这是困扰我的一个方面。类,尤其是复杂的类,变得越来越难以阅读。

4

12 回答 12

8

这确实是一个需要退后一步看大局的情况。Visual Studio 有许多工具可以帮助您编写和操作代码,包括大纲、#regions、类视图、类图、代码定义窗口等等。

C# 不是 C++,如果您尝试这样做,那么您将自己绊倒,其他人将无法阅读您的代码。

花一天时间学习使用 Visual Studio 工具将在生产力方面获得多倍的回报,您很快就会想知道您是如何使用 C++ 做事的方式生活的。

更新以回应评论

我早就停止将我的代码视为简单的文本文件。我将代码视为有机的东西,我发现允许自己依赖功能丰富的 IDE 可以让我更轻松地上下抽象级别,并不断提高我的工作效率。我想这可能是个人特质,也许并不适合所有人;我有一个非常“视觉”的头脑,当我能看到图片中的东西时,我工作得最好。

也就是说,一个聪明的 IDE 并不是糟糕风格的借口。编写不需要智能 IDE 的“干净代码”的最佳实践。干净代码的原则之一是使某些东西的定义接近其用途,我认为这可以扩展到涵盖声明和定义。就个人而言,我认为将声明和定义分开会使代码变得不那么清晰。如果你发现你得到了难以理解的怪物类,那么这可能表明你违反了单一职责原则。

在 c/C++ 中单独定义和声明的原因是因为 C++ 使用单遍编译器,其中前向引用不能在以后解析,这与 C# 及其两遍编译器不同无论声明的顺序如何,它都可以愉快地找到引用。这种差异源于编译器的不同设计理念:C/C++ 将每个源文件视为一个编译单元,而在 C# 中将整个项目视为编译单元。我想当你习惯于以 C/C++ 方式工作时,分离声明和定义似乎是一种可取的风格元素,但我个人认为保持声明和使用(或在这种情况下声明和定义)增强,而不是降低可读性。在 2001 年开始使用 C# 之前,我自己曾经是一名 C 程序员。我一直喜欢 C,并认为它的做事方式是“蜜蜂膝盖”。这些天,当我阅读 C/C++ 代码时,我认为它看起来非常可怕,我不能 不相信我们曾经忍受过这样的工作。我想这都是你习惯的问题。

于 2009-10-10T19:06:30.623 回答
7

如果您使用的是 Visual Studio,则可以利用类视图。您还可以使用源代码编辑器的展开/折叠功能。

在您的工具没有帮助的不太可能的情况下,您始终可以编写一个快速实用程序来为您总结课程。

如果类已经编译,你也可以使用 Reflector 来查看该类。

于 2009-10-10T18:44:51.180 回答
7

不,C# 中没有实现和头文件的概念,就像您在 C/C++ 中找到的那样。最接近这一点的是使用接口,但接口只能定义类的公共成员。然后,您最终会得到类和接口的一对一映射,这实际上并不是如何使用接口的意图。

于 2009-10-10T18:47:08.680 回答
3

定义一个接口。

然后很高兴能够使用一个不错的代码辅助工具自动实现接口。

于 2009-10-10T18:42:51.277 回答
3

您可以通过为每个类定义一个接口来获得类似的结果,然后它们将实现该接口。

于 2009-10-10T18:43:28.140 回答
3

听起来您指的是interfaces。在 C# 中,您可以在一个接口中定义所有成员函数,然后在另一个类中实现它们。

于 2009-10-10T18:44:04.507 回答
3

在 C# 中,您可以使用部分类和部分成员来伪造它,但是,前向声明和原型在您的新语言中会像渡渡鸟一样。类视图、类图、Intellisense 等都有助于消除对这些“特性”的潜在需求。

于 2009-10-10T18:48:57.757 回答
1

如果你发现某个课程难以阅读或难以理解,这通常表明该课程试图做得太多。与其尝试复制 C++ 的声明和定义分离,不如考虑将麻烦的类重构为多个类,从而减少每个类的责任。

于 2009-10-10T18:47:18.260 回答
1

只要有可能或需要,我都会使用以前的响应并定义一个接口。但这并不总是合适的。

或者,您可以使用一些静态代码检查工具来解决这个“问题”。Resharper 的“文件结构”窗口将为您提供所需的内容。您还可以使用 Visual Studio 中内置的“类视图”。但我更喜欢前者。

于 2009-10-10T18:47:37.913 回答
0

我猜您所指的原型在 C# 中并不存在。像其他人建议的那样定义接口会给你一个收集方法声明的点,但它与原型不同,我不确定它是否会帮助你使你的实现类更易于阅读。

C# 不是 C++,可能不应该被视为 C++。

于 2009-10-10T18:46:49.133 回答
0

有两种补救方法可以使它更像 C++:

  • 创建一个接口文件,声明所有方法签名和属性
  • partial通过在类定义上使用修饰符在一个类中跨多个文件实现该接口

编辑:

// File: ICppLikeInterface.cs
public interface ICppLikeInterface
{
    ...
}

// File: CppLikeImplementation1.cs    
public partial class CppLikeImplementation : ICppLikeInterface
{
    ...
}

// File: CppLikeImplementation2.cs    
public partial class CppLikeImplementation : ICppLikeInterface
{
    ...
}

将接口分离到头文件中的 C++ 方法主要是(我认为)由于早期的设计决定,当 C 被创建以允许在“过去”期间进行快速、增量编译时,编译器会丢弃任何元数据,与短暂聊天。这不是 C#(也不是 Java)的问题,在最近的硬件上,数万行代码可以在几秒钟内编译(C++ 仍然没有)

于 2009-10-10T18:49:51.780 回答
0

不知道你的意思是你的类继续增长并变得难以阅读。你的意思是你想要一个像班级成员视图这样的头文件吗?如果是这样,就像约翰建议的那样,你不能只是折叠实现,这样你就不必看到它了吗?

如果您不希望每个类都实现某件事,那么接口可能是要走的路(就像其他人所说的那样)。

但是作为一个侧面的想法,如果你的类本身在你编写程序时变得越来越复杂,那么它可能更像是一个设计问题而不是语言问题?我认为一个类应该有一个责任,而不是随着程序的增长承担越来越多的责任,而是随着你继续开发你的软件,类的数量和使用的旧类应该增长并变得更加复杂?

于 2009-10-10T18:52:19.840 回答