2008-11-26 2 views
20

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

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

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

ответ

22

Из Руководства каркаса (второе издание):

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

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

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

14

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

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

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

3

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

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

0

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

4

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

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

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

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

Смежные вопросы