【问题标题】:Is it ok to write my own extension methods in the system namespace?在系统命名空间中编写自己的扩展方法可以吗?
【发布时间】:2010-09-24 05:30:05
【问题描述】:

我最近一直在使用扩展方法,并发现它们有很多用途。我唯一的问题是记住它们在哪里以及使用什么命名空间来获取扩展方法。

但是,我最近想在 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();
        }
    }
}

这是正确的做法吗?

【问题讨论】:

    标签: c# .net extension-methods


    【解决方案1】:

    来自框架设计指南(第 2 版):

    不要将扩展方法放在与扩展类型相同的命名空间中,除非它是为了向接口添加方法,或者用于依赖管理。

    虽然这并未明确涵盖您的方案,但您通常应避免扩展框架命名空间(或任何您无法控制的命名空间),而是选择将这些扩展置于它们自己的命名空间中。如果您对“分组”扩展有强烈的感觉(例如集合扩展在一起等),那么您可以引入一个子命名空间。在您的场景中,集合的扩展将进入 System.Collection.Extensions 命名空间或 Company.Collections 甚至 Company.Collections.Extension 命名空间。

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

    【讨论】:

      【解决方案2】:

      您应该避免增加您没有主要控制权的命名空间,因为未来的更改可能会破坏您的代码(例如,通过引入重复项)。

      我倾向于使用不同的根命名空间来模仿标准命名空间,该根命名空间将所有子命名空间标识为属于我的工作。根命名空间可以是您的姓名、您所在组织的名称,或者可以将该命名空间的内容标识为您的其他名称。

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

      【讨论】:

        【解决方案3】:

        命名空间真正影响扩展方法的唯一因素是可见性和可发现性 - 因此这取决于您是否希望扩展方法始终出现在该类型上。框架设计指南主要针对公共 API,因此,虽然遵循它们通常是一个好主意,但在有意义的情况下,内部 API 的规则非常有待打破。

        例如,我们在整个代码库中使用 TimeSpan 对象做了大量工作,但在框架中没有方法可以将它们相乘或相除,因此我们添加了 MultiplyByDivideBy 扩展方法等,并将它们放在 System 命名空间中,因为我们希望它们在使用 TimeSpan 的任何地方都可以访问和发现。

        另一方面,我们也做了相当多的反射工作,对Type对象进行操作,并且有很多扩展方法在特定领域非常有用但不是一般的,所以这些都存在于@ 987654327@ 命名空间,因此必须专门导入它们。

        因此,对于内部 API,决定归结为“我是否希望此方法在我们代码库中可用类型的任何地方都可用?”。如果答案是肯定的,则将其放在同一个命名空间中,否则将其放在其他位置。

        【讨论】:

        • 在阅读您关于TimeSpan 的示例时,我意识到人们通常想要的不是一堆扩展方法,而是一种提供缺失功能的新类型。
        【解决方案4】:

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

        我认为真正的问题不在于将它们放在哪里或命名它(系统或任何其他名称空间),而是要保持一致并始终使用相同的名称来避免您的问题(忘记它们在哪里)。

        【讨论】:

          【解决方案5】:

          根据我希望它们具有的可见性,我将扩展方法放在命名空间中。这样他们更容易被发现,而且我通常会得到更少的命名空间导入。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-12-04
            • 1970-01-01
            • 1970-01-01
            • 2014-09-01
            • 2021-08-02
            • 1970-01-01
            • 2012-01-08
            相关资源
            最近更新 更多