我是一个相当新的 C# 和 .NET 开发人员。我最近使用 C# 创建了一个 MMC 管理单元,并且对它的简单性感到满意,尤其是在我的组织中的一些其他开发人员听到很多关于用 C++ 执行它有多难的恐怖故事之后。
我几乎在某个时候完成了整个项目,并将“public”关键字的每个实例都设置为“internal”,除非运行时需要运行管理单元。您对此有何感想,您通常应该将类和方法公开还是内部?
我相信尽可能使用黑盒。作为一名程序员,我想要一个定义明确的黑盒,我可以轻松地将它放入我的系统中并让它工作。我给它赋值,调用适当的方法,然后从中取回我的结果。
为此,只给我类需要公开工作的功能。
考虑电梯。为了让它去楼层,我按下一个按钮。那是黑匣子的公共接口,它激活了将电梯带到所需楼层所需的所有功能。
你所做的正是你应该做的;为您的班级提供尽可能低的知名度。哎呀,如果你真的想全心全意,你可以(最多)做所有事情 internal
并使用InternalsVisibleTo
属性,这样你就可以分离你的功能,但仍然不会将它暴露给未知的外部世界。
公开的唯一原因是您将项目打包在多个 DLL 和/或 EXE 中,并且(无论出于何种原因)您不想使用InternalsVisibleTo
,或者您正在创建一个供第三方使用的库。但即使在供第三方使用的库中,您也应该尽可能减少“表面积”;您可用的课程越多,您的图书馆就越混乱。
在 C# 中,确保您使用尽可能低的可见性的一种好方法是在您需要它们之前不使用可见性修饰符。C# 中的所有内容都默认为尽可能低的可见性:类内部的,类成员和内部类的私有。
我认为你应该在内部类和成员方面犯错。您始终可以增加项目的可见性,但降低它可能会导致问题。如果您正在为其他人构建框架,则尤其如此。
您确实需要小心,但不要向用户隐藏有用的功能。.NET BCL 中有许多有用的方法,如果不借助反射就无法使用。然而,通过隐藏这些方法,减少了必须测试和维护的表面积。
我更喜欢避免标记类,public
除非我明确希望我的客户使用它们,并且我准备支持它们。
我没有将类标记为internal
,而是将可访问性留空。这样一来,public
就显得格外引人注目。(当然,嵌套类除外,如果它们即使在同一个程序集中也可见,则必须对其进行标记。)
大多数类应该是internal
,但大多数非私有成员应该是public
。
关于成员,您应该问的问题是“如果创建了课程,public
我是否想让成员成员暴露?”。答案通常是“是(所以public
)”,因为没有任何可访问成员的类没有多大用处!
internal
成员确实有作用;它们是“后门访问”,仅适用于居住在同一个集会中的近亲。
即使您的班级仍然是内部的,也很高兴看到哪些是前门成员,哪些是后门成员。而且,如果您将其更改为公开,您将不必回过头来考虑哪些是哪些。
您应该倾向于尽可能少地向其他课程公开,并仔细考虑您公开的内容和原因。
您是否有任何理由需要使用内部而不是私有?您确实意识到 Internal 具有装配级别范围。换句话说,多类程序集中的所有类都可以访问内部类/成员。
正如其他一些答案所说,除非您实际上需要内部/受保护/公共,否则通常会尽可能地进行最高级别的封装(即私有)。
我发现尽可能使用内部类的问题。您不能让该类型(或参数类型或返回类型)的方法、属性、字段等比内部更可见。这导致具有内部的构造函数以及属性。这应该不是问题,但事实上,在使用 Visual Studio 和 xaml 设计器时,就会出现问题。设计人员检测到误报错误是因为方法不是公开的,用户控件属性似乎对设计人员不可见。我不知道其他人是否已经陷入了这样的问题......
您应该尽量使它们尽可能可见,但正如上面 Mike 所说,这会导致 UserControls 出现问题,并将 VS Designer 与表单或其他 UserControls 上的这些控件一起使用。
因此,作为一般规则,将您未使用设计器添加的所有类和用户控件仅在需要时保持可见。但是,如果您要创建一个要在设计器中使用的 UserControl(即使它在同一个程序集中),您需要确保 UserControl 类、其默认构造函数以及任何属性和事件都是公开的设计师使用它。
我最近遇到了一个问题,设计人员会不断从 InitializeComponent() 方法中删除 this.myControl = new MyControl() 行,因为 UserControl MyControl 与其构造函数一起被标记为内部。
我认为这确实是一个错误,因为即使它们被标记为内部,它们仍然显示在工具箱中以添加到设计器中,要么 Microsoft 只需要显示带有公共构造函数的公共控件,要么他们需要使其与内部控件一起使用好。
这取决于您对使用它的代码的控制程度。在我的 Java 开发中,我默认将我所有的东西都公开为 final,因为 getter 很烦人。但是,我也可以随时更改代码库中的任何内容。过去,当我不得不向消费者发布代码时,我总是使用私有变量和 getter。
我喜欢尽可能少地暴露事物。私有的、受保护的、内部的、公共的:为类、变量、属性和函数提供它们所需的最少可见性,以使所有内容仍能正常工作。
只有在有充分理由的情况下,我才会将某些东西的可见度提高到公开的链条上。
到目前为止,我完全不同意答案。我觉得 internal 是一个可怕的想法,阻止另一个程序集继承您的类型,甚至在需要解决方法时使用您的内部类型。
今天,我不得不使用反射来访问 System.Data.DataTable 的内部(我必须快速构建一个数据表,无需所有检查),我不得不使用反射,因为不是单一类型我可以使用;它们都被标记为内部。
默认情况下,类在 c# 中创建为内部:内部意味着:访问仅限于当前程序集。
请参阅 http://msdn.microsoft.com/en-us/library/0b0thckt.aspx
Good Article the defaults scope is internal: http://www.c-sharpcorner.com/UploadFile/84c85b/default-scope-of-a-C-Sharp-class/
不要选择“默认”。选择最适合该特定类别的可见性需求的内容。在 Visual Studio 中选择新类时,模板将创建为:
class Class1
{
}
这是私有的(因为没有指定范围)。您可以指定类的范围(或保留为私有)。应该有理由公开课程。