Можно ли писать собственные методы расширения в пространстве имен системы? - PullRequest
21 голосов
/ 26 ноября 2008

Я недавно использовал методы расширения и нашел для них множество применений. Единственная проблема, которую я имею, - это помнить, где они находятся и какое пространство имен использовать, чтобы получить методы расширения.

Однако недавно у меня появилась мысль написать методы расширения в пространстве имен 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 голосов
/ 26 ноября 2008

Из Руководства по проектированию рамок (2-е издание):

НЕ помещайте методы расширения в то же пространство имен, что и расширенный тип, за исключением случаев, когда они предназначены для добавления методов к интерфейсам или для управления зависимостями.

Хотя это явно не распространяется на ваш сценарий, вы, как правило, должны избегать расширения пространства имен Framework (или любого пространства имен, которое вы не можете контролировать), и вместо этого решили поместить эти расширения в свое собственное пространство имен. Если вы решительно настроены «сгруппировать» расширения (например, чтобы расширения коллекции были вместе и т. Д.), То вы можете ввести подпространство имен. В вашем сценарии расширение коллекций будет осуществляться в пространстве имен System.Collection.Extensions, Company.Collections или даже пространстве имен Company.Collections.Extension.

Чтобы использовать методы расширения, необходимо импортировать пространство имен, содержащее класс спонсора (класс, который определяет методы расширения). Если вы добавите методы расширения в одно из стандартных пространств имен .NET Framework, они всегда будут (и неявно) доступны.

14 голосов
/ 26 ноября 2008

Следует избегать расширения пространств имен, над которыми у вас нет основного контроля, поскольку будущие изменения могут нарушить ваш код (например, путем введения дубликатов).

Я склонен имитировать стандартные пространства имен с другим корневым пространством имен, которое идентифицирует все дочерние пространства имен как принадлежащие моей работе. Корневое пространство имен может быть вашим именем, названием вашей организации или чем-то еще, что идентифицирует содержимое этого пространства имен как ваше.

Например, если вы хотите расширить System.Collections, вы можете использовать NickR.Collections или NickR.System.Collections.

4 голосов
/ 01 декабря 2008

Единственное, что пространство имен действительно влияет на методы расширения, - это видимость и обнаруживаемость, поэтому все зависит от того, хотите ли вы, чтобы методы расширения всегда отображались в этом типе или нет. Руководящие указания по разработке каркаса предназначены в первую очередь для общедоступных API, и поэтому, как правило, им следует следовать, правила для них очень распространены, когда это имеет смысл.

Например, мы много работаем с TimeSpan объектами по всей кодовой базе, и нет никаких методов для их умножения или деления в рамках, поэтому мы добавили методы расширения MultiplyBy и DivideBy, среди прочего, и поместите их в пространство имен System, потому что мы хотим, чтобы они были доступны и обнаруживались везде, где используется TimeSpan.

С другой стороны, мы также выполняем довольно много работы по отражению, работая с Type объектами, и существует множество методов расширения, которые очень полезны в определенных областях, но не в целом, поэтому они живут в OurCompany.Reflection пространство имен, поэтому они должны быть специально импортированы.

Так что для внутренних API решение сводится к «хочу ли я, чтобы этот метод был доступен везде, где тип доступен в нашей кодовой базе?». Если ответ «да», поместите его в то же пространство имен, в противном случае поместите его где-нибудь еще.

3 голосов
/ 26 ноября 2008

Не уверен, что это неправильно (или правильно, если на то пошло), но почему бы не иметь свое собственное пространство имен «Расширения»? Затем поместите все свои методы расширения в это пространство имен и будьте последовательны в этом.

Я не думаю, что настоящая проблема в том, где их разместить или как их назвать (система или любое другое пространство имен), но чтобы быть последовательными и всегда использовать одно и то же, чтобы избежать вашей проблемы (забыв, где они находятся). 1003 *

0 голосов
/ 01 декабря 2008

Я помещаю свои методы расширения в пространство имен в зависимости от видимости, которую я хочу, чтобы они имели. Таким образом их легче обнаружить, и я обычно получаю меньше импорта пространства имен.

...