Подтвердить что ты не робот

Можно ли написать собственные методы расширения в системном пространстве имен?

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

Однако недавно я подумал о написании методов расширения в пространстве имен 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();
        }
    }
}

Это правильная вещь?

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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

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

Ответ 5

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