Почему генераторы кода всегда используют полностью квалифицированные идентификаторы?

Когда вы смотрите на код для Winforms Designer, вы увидите следующее:

this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", ... etc.

вместо

using System.Drawing;
label1.Font = new Font("Microsoft Sans Serif", ... etc.

То же самое относится к таким инструментам, как Linq to XSD , XSD2Code и, я подозреваю, Linq to SQL. Эти инструменты генерируют клады кода с чрезвычайно длинными полностью квалифицированными именами.

Не было бы проще создать соответствующие инструкции using и вырезать длинные имена? Или есть какая-то техническая причина для этого, что мне не хватает?


Примечание. . Для тех людей, которые сбиты с толку по понятию, что я, возможно, захочу, чтобы эти классы действительно были прочитаны человеком, обратите внимание, что это точно моя цель. У меня XSD с примерно 300 классами, я не хочу писать их вручную, и да, я бы хотел, чтобы они выглядели как обычный код, написанный людьми.

6 голосов | спросил Robert Harvey 13 FebruaryEurope/MoscowbWed, 13 Feb 2013 03:54:32 +0400000000amWed, 13 Feb 2013 03:54:32 +040013 2013, 03:54:32

4 ответа


20

Генераторы кода явно объявляют классы, которые они используют, чтобы предотвратить непредвиденное поведение от конфликтов имен.

Если проект включает класс с тем же именем, что и класс в другом пространстве имен, он вводит неоднозначность. Там, где есть неоднозначность, компилятор по умолчанию использует локальное пространство имен. Рассмотрим это:

using System.Drawing;

namespace MyProject {
    class MyClass {
        void InitialiseComponent() {
            this.label1.Font = new Font("Microsoft Sans Serif", ...);
        }
    }
}

Это прекрасно работает. Но что, если мы добавим в проект новый класс Font?

namespace MyProject {
    class Font : System.Drawing.Font {
        public Font(string fontName, ...) { ... }
    }
}

Теперь у нас есть System.Drawing.Font и MyProject.Font. Код в MyProject.MyClass.InitialiseComponent() все еще компилируется и запускается. Но какая версия Font использует?

Компилятор по умолчанию использует локальное пространство имен MyProject.MyClass и использует MyProject.Font, хотя using System.Drawing.

Это то, что хотел программист? Это не задача IDE, чтобы догадаться об этом. Программист должен явно указать, хотят ли они использовать их реализацию Font или System.Drawing.Font.

В рамках одного проекта IDE может обнаружить это изменение и изменить все созданные кодом файлы, чтобы выяснить, какой Font для использования. Но что, если проект в настоящее время не загружен? Как IDE может знать, какие файлы требуют дальнейшего обслуживания? Начните с того, чтобы быть конкретным, и никогда не бывает двусмысленности.

ответил Hand-E-Food 13 FebruaryEurope/MoscowbWed, 13 Feb 2013 05:01:34 +0400000000amWed, 13 Feb 2013 05:01:34 +040013 2013, 05:01:34
9

Генераторы кода обычно предназначены для создания машиносчитываемого кода больше, чем для человека, читаемого кодом. Предполагается, что люди в основном будут работать с исходным форматом, используемым в качестве входных данных для генератора. Операторы using повышают удобочитаемость человека, но компьютерам все равно.

Попробуйте выполнить описанный вами простой генератор кода, и вы поймете, почему они используют полностью квалифицированные имена. Обычно вы создаете какое-то абстрактное синтаксическое дерево на основе исходного формата ввода, затем вы идете по дереву для генерации кода. Использование операторов using требует хранения дополнительного «реестра» using, которые вы хотите использовать, проверяя его на дубликаты, затем возвращайтесь, чтобы вставить их в начало файла. Это стоит того, если это необходимо, например, выражение include, но это намного больше проблем, чем того, что стоит для чего-то с достаточно простым обходным решением ,

ответил Karl Bielefeldt 13 FebruaryEurope/MoscowbWed, 13 Feb 2013 04:14:21 +0400000000amWed, 13 Feb 2013 04:14:21 +040013 2013, 04:14:21
2

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

ответил Guy Coder 13 FebruaryEurope/MoscowbWed, 13 Feb 2013 03:58:33 +0400000000amWed, 13 Feb 2013 03:58:33 +040013 2013, 03:58:33
2

Сокращенные имена и using s полезны для написанного человеком кода, потому что:

  • разработчики предпочитают писать var defaultFont = new Font(...) по сравнению с var defaultFont = new System.Drawing.Font(...),

  • другие разработчики предпочитают читаемый код, а не что-то с длинными именами переменных и полностью квалифицированными типами.

Вот почему using s были изобретены в первую очередь. Мы могли бы указать полностью квалифицированные типы, но это сильно снизило бы квалификацию кода.

Не было бы проще вырезать длинные имена в сгенерированном коде? На самом деле, нет; на самом деле это не имеет значения. Когда код генерирует другой код, он не делает разницы между type.Name и type.FullName. Используя полные имена, генератору кода не нужно добавлять код using, что упрощает разработку генератора.


Я заметил, что вы прокомментировали ответ Карла Билефельда, написав:

  

Это здорово, если вы можете обрабатывать сгенерированный код как черный ящик и никогда не изменять его. Это не всегда так.

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

Если генераторы кода были написаны для людей, они бы сгенерировали код:

  • С еще несколькими комментариями

  • Правильно отступы,

  • Соблюдайте правила стиля (посмотрите, сколько предупреждений StyleCop вызвано сгенерированным кодом для простого класса Windows Forms),

  • С чистыми именами, которые не начинаются с @,

  • Модуль тестируется на регрессионное тестирование.

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

ответил Arseni Mourzenko 13 FebruaryEurope/MoscowbWed, 13 Feb 2013 04:15:14 +0400000000amWed, 13 Feb 2013 04:15:14 +040013 2013, 04:15:14

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132