Найти все помощники классов в Delphi во время выполнения с помощью RTTI?

Предлагает ли расширенный RTTI в Delphi 2010 способ перечисления определенных помощников классов и записей при запуске время?

Насколько я знаю, Delphi -vcl/" rel="noreferrer">не показывает подсказку или предупреждение, когда для класса определено более одного помощника класса, обнаружение помощника класса может быть полезной подпрограммой в "обеспечении качества".

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


person mjn    schedule 10.02.2010    source источник
comment
Неважно, определено ли во время выполнения более одного помощника. Если вы попытаетесь использовать методы, представленные помощником, отличным от недавно определенного, ваш код даже не скомпилируется, поэтому нет времени выполнения.   -  person Rob Kennedy    schedule 10.02.2010
comment
@Rob: цитата со связанной страницы (Turbocharging Delphi 2010): вы можете определить и связать несколько помощников класса с одним типом класса - означает ли это, что если я свяжу несколько помощников класса с одним классом, код больше не будет компилироваться?   -  person mjn    schedule 10.02.2010
comment
Вы можете создать несколько помощников, но одновременно будет действовать только один. Пожалуйста, продолжайте читать предложение, которое вы только что процитировали: в любом конкретном месте исходного кода применяется только ноль или один помощник класса. Будет применяться помощник класса, определенный в ближайшей области. Область действия помощника класса определяется обычным способом Delphi (т. е. справа налево в предложении использования модуля).   -  person Rob Kennedy    schedule 10.02.2010
comment
Теперь я понял ваш первый комментарий :)   -  person mjn    schedule 10.02.2010


Ответы (1)


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

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

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

По этой причине их внедрение в язык решало вполне специфические задачи, а именно возможность «явиться» для внедрения функционала в существующий фреймворк. Пока вы придерживаетесь правила «только один помощник» и не отклоняетесь от этого пути, вы можете выйти относительно невредимым. Несмотря на это, вам понадобится объединенная внутренняя стойкость Беовульфа, Леонидаса (Спарты) и Фродо Бэггинса, чтобы перемещаться по этим водам.

Учитывая, что здесь, в команде RAD Studio, мы не хотим когда-либо использовать помощника класса там, где его можно избежать. И когда мы их используем, соответствующая фаланга формируется еще до того, как мы начинаем...

Здесь драконы...

person Allen Bauer    schedule 10.02.2010
comment
+1 за драконов. :-) Ну, вы должны были ввести новую видимость для помощников класса под названием Intestinal и зарезервировать ее для команды R&D и нескольких паладинов на переднем крае... ‹G› - person Francesca; 10.02.2010
comment
Знаешь, мне всегда было интересно, почему это реализовано именно так. Почему помощники классов должны быть такими страшными, что их боится даже команда Delphi? Почему мы ограничены использованием только одного на классе в любой момент времени? - person Mason Wheeler; 10.02.2010
comment
В основном это связано с правилами области видимости языка. Мы не собирались нарушать эти правила, так как это создало бы еще большую путаницу. Они не страшны, если и только если вы действительно понимаете правила и их подводные камни. Проблемы возникают, когда вы используете помощники как неотъемлемую часть API вашего фреймворка. Тогда вы рискуете столкнуться с дуэльными помощниками. - person Allen Bauer; 10.02.2010
comment
@Mason: Потому что они никогда не предназначались для расширения языка общего назначения !!! Они были введены для решения очень специфической проблемы в VCL. Документация всегда предостерегала людей НЕ использовать их для более общих целей (и есть альтернативные методы, которые достигают того же самого И БОЛЬШЕ, которые имхо лучше (более непрозрачны) и всегда работали во всех версиях Delphi!) - person Deltics; 11.02.2010
comment
@Deltics: Нет, есть несколько вещей, которые могут делать только помощники класса, например добавить метод к базовому классу (и всем его потомкам), который может использовать защищенные члены этого класса. Нет другой языковой функции, которая может сделать это, насколько я знаю. Кроме того, если бы это было реализовано должным образом, это было бы намного полезнее. Взгляните на LINQ, чтобы увидеть, чего можно добиться с помощью правильно выполненных расширений классов. - person Mason Wheeler; 11.02.2010
comment
Что именно будет правильно реализовано? Это очень расплывчатое заявление. Сделать их похожими на методы расширения C# — это не выход. И помните, что методы расширения C# также имеют схожие правила области видимости и могут доставить вам столько же неприятностей. Методы расширения — не единственное, что делает LINQ, LINQ. Это интенсивное использование вывода типов и API-интерфейса Fluent Style, который делает это. - person Allen Bauer; 11.02.2010
comment
@Mason: для этого вы можете реализовать расширитель класса psuedo. Единственное отличие состоит в том, что для использования этого псевдо-расширителя вы должны явно выполнить приведение к нему. Но я вижу в этом преимущество для обслуживания кода, потому что становится совершенно очевидным, что то, что вы делаете, не поддерживается экземпляром напрямую, а использует трюк. С помощником класса тот факт, что метод не поддерживается напрямую экземпляром, запутывается, и с потенциально несколькими существующими помощниками класса, но только с одним помощником в области видимости, изменение области действия может нарушить код так, как не могут явные псевдоприведения. - person Deltics; 11.02.2010
comment
@Mason 2: Нет ничего, что может сделать помощник класса, чего не могут сделать альтернативные методы, за исключением того факта, что помощник класса делает это менее непрозрачным, более прозрачным, более хрупким способом и, следовательно, более опасен. Введение помощника класса A - возможно, неосознанно/непреднамеренно - может сломать [неудачную компиляцию] ранее корректного кода, уже использующего помощника класса B, или повредить его [если оба помощника предоставляют методы с одинаковыми именами, но выполняют немного разные вещи]. - person Deltics; 11.02.2010