21

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

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

这是正确的做法吗?

4

5 回答 5

22

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

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

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

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

于 2008-11-26T20:20:02.570 回答
14

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

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

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

于 2008-11-26T19:52:21.067 回答
4

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

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

另一方面,我们也做了相当多的反射工作,对Type对象进行操作,并且有很多扩展方法在特定领域非常有用,但并不普遍,所以它们存在于OurCompany.Reflection命名空间中,所以它们必须专门进口的。

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

于 2008-12-01T02:31:02.760 回答
3

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

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

于 2008-11-26T19:52:25.293 回答
0

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

于 2008-12-01T01:31:15.003 回答