C#类函数成员声明和实现

6
在C#中是否存在与C++中的类定义和实现类似的概念?
我更喜欢通过删除大多数,甚至所有实现细节(这取决于几个因素,但通常我会将大多数成员实现细节留在类定义之外)来保持类定义简单。这有利于给我一个俯视类及其功能的视图。
然而,在C#中似乎我被强制在声明时定义我的成员函数。是否可以避免这种情况,或者以某种方式规避?
在学习C#期间,这是困扰我的一个方面。特别是复杂的类变得越来越难阅读。
12个回答

8
这实际上需要退一步看整个大局。Visual Studio有许多工具可帮助您编写和操作代码,包括大纲、#region、类视图、类图、代码定义窗口等等。
C#不是C++,如果您试图这样做,那么您会被绊倒,其他人也无法阅读您的代码。
花一天时间学习使用Visual Studio工具将以生产力的形式多次回报您的投资,并且您很快就会想知道您如何使用C++完成任务。
更新以响应评论
我早已停止将我的代码视为简单的文本文件。我认为代码是一种有机的东西,而且我发现允许自己依赖功能丰富的IDE可以更轻松地在抽象层次之间移动,并极大地提高了我的生产力。我想这可能是个人特质,也许并不适合每个人;我有一个非常“视觉化”的头脑,当我能够以图片的形式看到事物时,我最有效率。
说到这一点,聪明的集成开发环境并不是糟糕代码的借口。有编写"干净代码"的最佳实践,不需要一个智能IDE。其中之一是编写干净代码的原则是将某些东西的定义保持在其使用附近,我认为这可以扩展到包括声明和定义。个人认为,分离声明和定义会使代码变得更加不清晰。如果你发现自己得到了难以理解的大型类,那可能就说明你正在违反单一责任原则。
在C/C++中分别定义和声明的原因是因为C++使用单遍编译器,无法像C#及其双遍编译器一样轻松地找到引用,而后者可以不考虑声明顺序。这种差异源于编译器的不同设计理念:C/C++认为每个源文件都是一个编译单元,而在C#中整个项目被视为编译单元。我想当你习惯于以C/C++方式工作时,将声明和定义分开可能会显得更具有吸引力,但我个人认为保持声明和使用(或在这种情况下是声明和定义)可以增强可读性,而不是减少可读性。我曾经也是一名C程序员,直到2001年开始使用C#。我一直喜欢C,并认为它的做事方式是“最好的”。如今当我阅读C/C++代码时,我觉得它看起来非常可怕,我无法相信我们曾经容忍过这种工作方式。我想这只是习惯问题。

3
我不完全不同意你的看法,Tim。但是,虽然这些都很好,但这个哲学本质上意味着只有在使用功能丰富的集成开发环境时,我才能理解我的代码。现在...这并没有给我带来太多的安慰。 - Alexandre Bell

7
如果您使用的是Visual Studio,您可以利用Class View。您还可以使用源代码编辑器的展开/折叠功能。
在极少数情况下,如果您的工具无法帮助您,您总可以编写一个快速实用程序来为您总结类。
如果类已经被编译,您也可以使用Reflector查看类。

此外,类图工具非常适合获取鸟瞰视图。 - Tim Long

7

在C#中,没有像C/C++中那样的实现和头文件的概念。你可以使用接口来实现类似的功能,但是接口只能定义类的公共成员。这样你最终会得到一个类和接口之间的1对1映射,但这并不是接口的真正用途。


3

定义一个接口。

然后,使用一个好的代码辅助工具自动实现接口是很不错的。


或者是一个抽象类。但那样做很愚蠢。 - Philippe

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

好的,我想我明白你的意思了。使用我的类型接口来代替类,而不是类本身。虽然不完全符合我的期望,但确实可以解决问题。这也回答了我的问题 :) 没有一种方法可以将成员实现细节与类定义分离。 - Alexandre Bell
3
接口并不是正确的方法,因为它们只能包含类的 公共 成员。在C#中无法实现与头文件相同的结果。 - Scott Dorman
6
我不会盲目追随这个原则。你不应该仅为了方便自己阅读而为类定义接口。到处定义接口可能会使代码的维护变成一场噩梦。 - Moshe Levi
当然同意。我注册了这个可能性,但实际上并不打算实现它 :) - Alexandre Bell

3

看起来你在谈论 接口。在C#中,你可以在接口中定义所有成员函数,并在另一个类中实现它们。


3
你可以在接口中定义所有公共成员函数,但是你不能定义任何访问权限。 - Scott Dorman

3
在C#中,您可以使用部分类和部分成员来模拟一定程度的前向声明和原型,然而,在新的语言中,这些特性已经逐渐消失了。类视图、类图、Intellisense等工具都有助于消除对这些“特性”的潜在需求。

1
如果您发现一个类很难阅读或理解,那通常意味着该类试图做太多的事情。不要试图复制C++中声明和定义的分离,考虑将问题类重构为几个类,以便每个类具有较少的职责。

2
这非常具有争议。这取决于问题领域。 - Alexandre Bell

1
每当可能或可行时,我会采用先前的回应并定义一个接口。但这并不总是合适的。
或者,您可以通过使用一些静态代码检查工具来解决这个“问题”。ReSharper的“文件结构”窗口将给您提供所需的内容。您还可以使用Visual Studio内置的“类视图”。但我更喜欢前者。

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语言创建时做出的,以便在“旧日子”进行快速、增量编译,因为编译器会丢弃任何元数据,与Smalltalk相反。这对于C#(或Java)不是问题,在最新的硬件上,成千上万行的代码可以在几秒钟内编译(C++仍然无法做到)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接