Должен ли я использовать (в противном случае оптимальные) имена классов, которые конфликтуют с именами .NET BCL? - PullRequest
10 голосов
/ 06 августа 2010

Эта ситуация, вероятно, не является чем-то необычным для некоторых из вас: у вас есть некоторая функциональность для помещения в класс, но идеальное имя (*) для этого класса берется одним из классов в пространстве имен System или другом пространстве имен/ класс не твой, но ты using / import ing.

(*) Под идеальным я подразумеваю маленькие, лаконичные и ясные имена.

Например, у меня есть класс Utils, который имеет класс Diagnostics (главным образом, утилиты отладки) и класс Drawing.Я мог бы:

  1. иметь класс DrawingUtils и класс DiagnosticsUtils, но это просто пахнет как плохая структура.
  2. выберите тезаурус и покончите с более худшим, длинным или неловким именем, которое по-прежнему не принято.
  3. Пишите имена классов на моем родном языке вместо английского.
  4. Спросите умных парней в StackOverflow.

Я думаю, варианты 1-3 не обещают:(

РЕДАКТИРОВАТЬ:

Поскольку мой выбранный ответ не решает проблему окончательно (как и я), , что я бы порекомендовал для людей, сталкивающихся с такой же ситуацией:Спросите себя: будете ли вы часто использовать конфликтующее класс / пространство имен BCL? Если нет, тогда пусть ваше имя конфликтует (как я делал с Diagnostics). Если да, добавьте слово, которое ограничивает возможности вашего класса/namespace.

На практике это означает:
"Drawing": что-то, что рисует.
"MyCustomControlDrawing": что-то, что рисует только вклMyCustomControl. Например: "WidgetDrawing".

EDIT2:

Еще одно решение, чтобы посмотреть в следующий раз: Методы расширения (любезно предоставлено Газонокосилка ).

Ответы [ 7 ]

8 голосов
/ 06 августа 2010

Я не вижу проблем с сохранением имен Drawing, Diagnostics и т. Д. Это одна из целей пространств имен для разрешения конфликтов имен.

6 голосов
/ 06 августа 2010

Прелесть пространств имен в том, что они позволяют создавать классы с одинаковыми именами. Вы можете назначить псевдоним пространству имен при импорте его в файл с помощью оператора using.

using MyAlias = My.Custom.Namespace;

это будет держать ваши классы отдельно от Microsoft.

тогда вы можете ссылаться на ваши классы как

MyAlias.Diagnostics

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

5 голосов
/ 06 августа 2010

Мне действительно не стоит целенаправленно писать конфликтующие имена классов. Вы будете путать других разработчиков, которые не знакомы с вашей кодовой базой, потому что они ожидают использовать классы BCL, но вместо этого получат ваши (или наоборот). Затем вы просто тратите свое время, когда им приходится писать конкретные using псевдонимы.

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

РЕДАКТИРОВАТЬ : Я также не верю, что «маленький» является компонентом «идеального» идентификатора. Конечно, кратко и ясно, но если для обозначения цели конкретной конструкции требуется более длинное имя, пусть будет так. В конце концов, у нас есть интеллигенция.

4 голосов
/ 06 августа 2010

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

using Type = MyReallyCoolCustomReflector.Type;

Теперь, если вы хотите использовать класс Type из пространства имен System:

System.Type sysType = anObject.GetType();

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

1 голос
/ 06 августа 2010

Часто можно выбрать более конкретное имя. Возьмите Utils для примера. Абсолютно все можно назвать утилитой. Для читателя вашего кода это имя класса ничего не стоит.

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

В целом:

  1. Это то, что мы делаем (эй, мы можем изменить его позже)

  2. Используется один или два раза, но только на важных классах. Особенно полезно, если вы еще не знаете «идеальное» имя.

  3. даже не думай об этом ...

Использовать псевдонимы пространства имен не весело. Поэтому я избегаю этого, если смогу.

1 голос
/ 06 августа 2010

Только для справки: .NET Framework не имеет ни Utils, ни Diagnostics класса.(Но у него есть System.Diagnostics пространство имен.)

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

В остальном - я согласен с другими в том, что пространства имен удобны.(Хотя я бы дважды подумал назвать этот класс, если в System уже есть класс с таким же именем, не из-за конфликтов имен, а потому, что причина, по которой я не могу использовать «оригинальный» класс, может означать, чтокласс, который я собираюсь создать, семантически отличается.)

1 голос
/ 06 августа 2010

Что ж, если вы хотите избежать столкновения пространства имен, вы можете сделать несколько вещей:


  • Не сталкивайтесь, вместо этого выберите уникальное имя.

Пример:

Если вы создаете класс по математике, вы можете назвать свой CamiloMartin.MathHelper


  • Использовать длинное пространство имен дляразличать столкновения.

Пример:

public class MyClass
{
    public int SomeCalculation(int a, int b)
    {
        return MyNamespace.Math.SomeFunc(a, b);
    }
}

  • Использование псевдонима для дифференциации.

Пример:

using System.Math;
using SuperMath = MyNamespace.Math;

namespace MyNamespace
{
    public class MyClass
    {
        public int SomeCalc(int a, int b)
        {
             int result = Math.abs(a);
             result = SuperMath::SomeFunc(a, b);

             return result;
        }
    }
}
...