在系统命名空间中编写自己的扩展方法是否可以?

22

最近我经常使用扩展方法,并发现它们有很多用途。唯一的问题是我记不住它们在哪里,以及为了获取扩展方法需要使用哪个命名空间。

然而,我最近想到一个办法,就是将扩展方法写在 System 命名空间、System.Collections 命名空间或其他一些有意义的系统命名空间中。例如,我已经实现了以下扩展方法。

namespace System
{
    /// <summary>Various array extensions</summary>
    public static class ArrayExtensions
    {
        /// <summary>Converts the array to a hex string</summary>
        /// <param name="value">The value.</param>
        /// <returns>The array as a hex string</returns>
        public static string ToHexString(this byte[] value)
        {
            var hex = new StringBuilder(value.Length * 2);
            foreach (byte b in value)
            {
                hex.AppendFormat("{0:X2}", b);
            }
            return hex.ToString();
        }
    }
}

这样做是正确的吗?

5个回答

22

根据《框架设计指南(第二版)》:

除非扩展方法用于添加接口方法或依赖管理,否则不要将其放在扩展类型相同的命名空间中。

虽然这并没有明确涉及您的情况,但通常应避免扩展框架命名空间(或任何您无法控制的命名空间),而是选择将这些扩展置于它们自己的命名空间中。如果您坚持“分组”扩展(例如,将集合扩展放在一起等),那么可以引入子命名空间。在您的情况下,针对集合的扩展将放在System.Collection.Extensions命名空间、Company.Collections命名空间甚至Company.Collections.Extension命名空间。

为了使用扩展方法,必须导入包含主类(定义扩展方法的类)的命名空间。如果将扩展方法添加到标准.NET Framework命名空间之一,则它们将始终(且隐式地)可用。


14

在IT技术中,你应该避免扩展那些你无法控制的主命名空间,因为未来的更改可能会破坏你的代码(例如引入重复项)。

我倾向于使用不同的根命名空间来模仿标准命名空间,并将所有子命名空间标识为属于我的工作。根命名空间可以是你的名字、你组织的名称或其他能够识别该命名空间内容为你自己的东西。

例如,如果你想要扩展System.Collections,你可以使用NickR.CollectionsNickR.System.Collections

4
命名空间对于扩展方法真正影响的只有可见性和发现性,因此这取决于您是否希望扩展方法始终出现在该类型上。框架设计准则主要用于公共 API,因此,虽然遵循它们通常是个好主意,但当对内部 API 有意义时,规则往往被打破。
例如,我们在整个代码库中都使用TimeSpan对象,并且框架中没有乘法或除法方法,因此我们添加了MultiplyBy和DivideBy等扩展方法,并将它们放在System命名空间中,因为我们希望无论何时使用TimeSpan时都可以访问和发现它们。
另一方面,我们还会进行相当多的反射工作,操作Type对象,并且有许多特定领域非常有用的扩展方法,但并不普遍使用,因此这些方法位于OurCompany.Reflection命名空间中,因此必须明确导入。
因此,对于内部 API,决策归结为“我是否希望该方法在我们代码库中的每个地方都可用?”如果答案是肯定的,则将其放在同一个命名空间中,否则将其放在其他地方。

在阅读有关TimeSpan的示例时,我意识到人们通常想要的不是一堆扩展方法,而是一个新类型,它将提供缺失的功能。 - csharpfolk

3

不确定是否正确(或错误),但为什么不创建自己的“Extensions”命名空间?然后将所有扩展方法放在该命名空间中,并保持一致性。

我认为真正的问题不在于放置在哪里或如何命名它们(系统或任何其他命名空间),而在于始终保持一致,避免出现问题(忘记它们在哪里)。


0

我会根据我想要的可见性将我的扩展方法放在一个命名空间中。这样它们更容易被发现,而且我通常会少导入一些命名空间。


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