是否有任何最佳做法表明自定义代码不应放在System
命名空间中?是否应为System
及其子代保留Microsoft代码?
我问,因为我正在编写一个将在许多项目中使用的类库,我希望通过将它放在System.InteropServices
中来保持一致(因为它处理P / Invoke)。
答案 0 :(得分:11)
这不是一个好主意,因为它破坏了名称空间的主要好处之一:防止名称冲突。如果更新版本的框架在该命名空间中引入了同名的类型,该怎么办?
这对于System
命名空间来说特别糟糕,因为它们是在带有using
指令的许多其他代码段中导入的,并且在这些命名空间中引入自定义类型会污染具有意外标识符的其他源文件的命名范围。
要对自定义互操作相关类型进行分类,您可以创建一个新的名称空间,如MyProduct.InteropServices
。
答案 1 :(得分:2)
如果在System.InteropServices
中放置一个新类,则每个具有using System.InteropServices;
子句的文件都被强制将您的类放在范围内,这可能会使程序员感到困惑。由于程序员不能反对这一点,我会考虑这种不好的做法。
答案 2 :(得分:2)
我不同意所有人的意见。
我认为在一个有限的案例子集中(主要是使用扩展方法),将代码放在系统命名空间中是完全合理的。
以下是我在电子邮件主题中提出的论点,我们在EPS处讨论了System命名空间中的扩展方法:
好的,所以这是我的观点:
我真的想最小化代码。这包括使用。
是的,ReSharper选择了扩展方法并为你添加了使用方法,但有些人没有ReSharper,而且我更喜欢Coderush,但实际上并没有(据我所知)拿起扩展名称空间。
至少有两种不同类型的扩展方法;那些是我们的应用程序的辅助方法 - 包括域和特定于应用程序的帮助程序,以及封装我们认为该语言应该必须开始的功能和语法的那些。
后者的一个很好的例子是能够"a {0} {1}".Format("b", "c")
或someListOfStrings.Join(", ")
而不是String.Join(someStringList.ToArray(), ", ")
。其他更有争议的示例是IEnumerable<T>.ForEach
和IsNull()
扩展,以取代笨拙的object.ReferenceEquals(null, someVar)
语法。
我的论点是,完全有理由将后一种分类 - 你的团队广泛认同应该使用语言但不是 - 在适当的命名空间(System,System.IO,System.Linq等) 。我们希望这些功能随处可用,就像我们更喜欢foreach和yield关键字一直可见。如果它是特定于应用程序的,那么它应该在它自己的命名空间中。 90%的特定于应用程序的帮助程序扩展可能不是扩展,甚至不是静态的。我使用扩展方法从此语句中排除了为函数名提供别名。
当调用包含系统范围扩展的程序集时,当然可能会遇到一些麻烦。假设我正在引用包含我的void IEnumerable<T>.ForEach
方法的程序集,并且想要创建我自己的ruby-like R IEnumerable<T, R>.ForEach
(实际上它只是一个Select,但没关系)。这将是一个问题!我想要解决的问题是将扩展类定义为内部,以便它们只能在我的项目中使用。这很好地解决了这个问题。