Можно ли написать собственные методы расширения в системном пространстве имен?
Я недавно использовал методы расширения и нашел для них много возможностей. Единственная проблема, с которой я сталкиваюсь, - это запомнить, где они находятся, и какое пространство имен использовать для получения методов расширения.
Однако недавно я подумал о написании методов расширения в пространстве имен 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();
}
}
}
Это правильная вещь?
Ответы
Ответ 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
Я помещаю свои методы расширения в пространство имен в зависимости от видимости, которую я хочу иметь. Таким образом, их легче обнаружить, и я обычно получаю меньше импорта пространства имен.