将自定义代码放在System命名空间中

是否有任何最佳实践表明自定义代码不应放在System命名空间中? System及其System应该保留给Microsoft代码吗?

我问,因为我正在编写一个将在许多项目中使用的类库,并且我希望通过将它放在System.InteropServices来保持一致(因为它处理P / Invoke)。

这不是一个好主意,因为它破坏了命名空间的主要好处之一:防止名称冲突。 如果更新版本的框架在该命名空间中引入了同名的类型,该怎么办?

这对于System命名空间来说尤其糟糕,因为它们using指令在许多其他代码段中导入,并且在这些命名空间中引入自定义类型会污染具有意外标识符的其他源文件的命名范围。

要对自定义互操作相关类型进行分类,可以创建一个新的命名空间,如MyProduct.InteropServices

如果在System.InteropServices放置一个新类,则每个文件都有一个using System.InteropServices; 子句被强制让你的类在范围内,这可能会使程序员感到困惑。 既然程序员不能为此辩护,我会考虑这种不好的做法。

我不同意所有人的意见。

我认为在一个有限的案例子集中(主要是使用扩展方法)将代码放在系统命名空间中是完全合理的。

以下是我在电子邮件主题中论证的一方,我们在EPS中讨论了System命名空间中的扩展方法:


好的,所以这是我的观点:

  1. 我真的很想最小化代码。 这包括使用。

  2. 是的,ReSharper选择了扩展方法并为你添加了使用,但有些人没有ReSharper,而且我更喜欢Coderush,但实际上并没有(据我所知)获取扩展命名空间。

  3. 至少有两种不同类型的扩展方法; 那些是我们的应用程序的辅助方法 – 包括域和特定于应用程序的帮助程序,以及封装我们认为该语言应该必须开始的function和语法的程序。

后者的一个很好的例子是能够执行"a {0} {1}".Format("b", "c")someListOfStrings.Join(", ")而不必执行String.Join(someStringList.ToArray(), ", ") 。 其他更有争议的例子是IEnumerable.ForEachIsNull()扩展,取代了笨拙的object.ReferenceEquals(null, someVar)语法。

我的论点是,有充分的理由将后一种分类 – 你的团队广泛认同应该在语言中而不是 – 在适当的命名空间(System,System.IO,System.Linq等)中。 我们希望这些function随处可用,就像我们更喜欢foreach和yield关键字一直可见。 如果它是特定于应用程序的,那么它应该在它自己的命名空间中。 90%的特定于应用程序的帮助程序扩展应该不是扩展,甚至不是静态的。 我使用扩展方法从此语句中排除为函数名称提供别名。

当你调用包含系统范围扩展的程序集时,你当然会遇到一些麻烦。 假设我正在引用包含我的void IEnumerable.ForEach方法的程序集,并且想要创建我自己的ruby-like R IEnumerable.ForEach (实际上它只是一个Select,但没关系)。 这将是一个问题! 我想要解决的问题是将扩展类定义为内部类,以便它们只能在我的项目中使用。 这很好地解决了这个问题。