powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Дженерики: передача процедуры в качестве параметра
25 сообщений из 108, страница 3 из 5
Дженерики: передача процедуры в качестве параметра
    #39725501
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite,

не это почти то же самое, только с использованием лямбла-функций?
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725504
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_BX11Не смог найти.
Поэтому вопрос.
А есть ли у Delphi встроенный способ создать словарь с регистронезависимым (case-insensitive) поиском по ключам?
Или нужно самому пилить?

Код: pascal
1.
 FClassesList := TDictionary<string, TForm>.Create(TIStringComparer.Ordinal);



Не понял... недавно использовал именно TIStringComparer.Ordinal и регистронезависимость не работала, а теперь работает

ок. наверное я где-то ещё обшибся.
спасибо
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725513
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11Valery_Bпропущено...


Код: pascal
1.
 FClassesList := TDictionary<string, TForm>.Create(TIStringComparer.Ordinal);



я пробовал Ordinal - он регистразависим

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
procedure TForm1.Button1Click(Sender: TObject);
var
 FDict:TDictionary<string, string>;
begin
  FDict:=TDictionary<string, string>.Create(TIStringComparer.Ordinal);
  try
   FDict.Add('hEllOwOrlD','Всем привет');
   ShowMessage(FDict['HelloWorld']);
  finally
   FDict.Free;
  end;
end;
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725521
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725524
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11Не понял... недавно использовал именно TIStringComparer.Ordinal и регистронезависимость не работала, а теперь работает

ок. наверное я где-то ещё обшибся.
спасибо
Ок.
По теме - не создавай функции/процедуры, а создавай классы.
Как было предложено ранее:
Код: pascal
1.
2.
3.
4.
5.
6.
TBot  = class
...
end;
И их производные.
TSuperBot = class(TBot)
TKillerBot = class (TBot)


С таким кодом, будет гораздо проще работать и понимать.
Ты всегда можешь инициализировать класс так, как нужно тебе в конкретном случае.
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725525
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_B, да верю, я верю, уже перепроверил и убедился, что ты прав.

Я не знаю, что не так у меня было в пенрвый раз, почему не сработало. Я именно с TIStringComparer.Ordinal и начинал.

вот и в справке написано:Возвращает объект TStringComparer, который выполняет сравнение строк с учетом регистра

...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725528
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11Не понял... недавно использовал именно TIStringComparer.Ordinal и регистронезависимость не работала, а теперь работает

Вру. Скорей всего я "TIStringComparer.Ordinal" хотел использовать, но не использовал, т.к. полез в справку, а там написано, что - зависит от регистра.
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725530
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11Я не знаю, что не так у меня было в пенрвый раз, почему не сработало. Я именно с TIStringComparer.Ordinal и начинал.

Такое у всех было)
Потому что ты делал это в большом проекте, и тестировал не в тех местах.
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725536
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лол, чудаки из эмбы свою справку так и не исправили -- до сих пор стоит текст про регистрозависимость:
http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Generics.Defaults.TIStringComparer.Ordinal

Тогда как в коде там AnsiLowerCase используется (т.е. не зависит от регистра):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function TOrdinalIStringComparer.Compare(const Left, Right: string): Integer;
var
  L, R: string;
  len, lenDiff: Integer;
begin
  L := AnsiLowerCase(Left); 
  R := AnsiLowerCase(Right); 
  len := Length(L);
  lenDiff := len - Length(R);
  if Length(R) < len then
    len := Length(R);
  Result := BinaryCompare(PChar(L), PChar(R), len * SizeOf(Char));
  if Result = 0 then
    Exit(lenDiff);
end;
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725548
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JaDi,

Ха, прикольно... Ребята жгут
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39725697
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, если правильно помню, то использование такого словаря приводило к утечке памяти в одной из версий делфи
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39726351
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JaDi
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
function TOrdinalIStringComparer.Compare(const Left, Right: string): Integer;
var
  L, R: string;
  len, lenDiff: Integer;
begin
  L := AnsiLowerCase(Left); 
  R := AnsiLowerCase(Right); 
  len := Length(L);
  lenDiff := len - Length(R);
  if Length(R) < len then
    len := Length(R);
  Result := BinaryCompare(PChar(L), PChar(R), len * SizeOf(Char));
  if Result = 0 then
    Exit(lenDiff);
end;


Неужели две конвертации строк и бинарное сравнение быстрее непосредственного сравнения без учета регистра?
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39726375
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Василий 2,

А что такое "непосредственное сравнения без учета регистра" ?
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39726581
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zinpubВасилий 2,

А что такое "непосредственное сравнения без учета регистра" ?
AnsiCompare с параметром
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39726609
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Василий 2,

Да так быстрее, но CompareString - на мой взгляд, несколько не подходит в данном случае, тк результат сравнения не всегда однозачен...
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729479
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Немножко переделал. Теперь в словаре живут не ссылки процедуры, а строковые имена процедур.
Кто работал с RTTI, пожалуйста, подскажите, как выполнить метод по имени.
Читаю про TRttiContext, TRTTIType и TRTTIMethod примеры и справку, не могу врубиться.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Var
  BotProc: TBotProc;// её нужно выполнить
  BotProcName: string;// ссылка на процедуру
  ctx: TRttiContext;
  rtype: TRTTIType;
  rmethod: TRTTIMethod;
begin
...
...

  if DicCmds.ContainsKey(sInCmd) then
  begin
    BotProcName := DicCmds[sInCmd];

    rtype := ctx.GetType(self.ClassType);
    rmethod := rtype.GetMethod(BotProcName);

  дальше что ? здесь застрял

    if Assigned(BotProc) then// если нашли
      BotProc(AMessage.Text, AMessage.From);
  end;


спасибо
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729489
Tactical Nuclear Penguin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
rmethod.Invoke ?
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729540
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вроде бы, но не разобрался как правильно ему передать параметры
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729568
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
rmethod.Invoke(Self, TArray<TValue>.Create(TValue.From<string>('AMessage.Text'), TValue.From<string>('AMessage.From')));


В вашем случае скорее всего так...
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729570
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ошибся выше, надо так:
Код: pascal
1.
rmethod.Invoke(Self, TArray<TValue>.Create(TValue.From<string>(AMessage.Text), TValue.From<string>(AMessage.From)));
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729612
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Весело настанет когда, пользователь случайно, а может и не случайно используя уже какой - то метод, вызовет Invoke с типом объявленным посредством type тот же type myString = string и не сможет вызвать с этим аргументом
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729760
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гирлионайльдо, не понял...
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729764
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема в том, что
Код: pascal
1.
rmethod := rtype.GetMethod(BotProcName);


не находит нужный метод, хотя он 100% есть у формы:



хотя метод PcmdStart объявлен в секции private формы:
Код: pascal
1.
    procedure PcmdStart(const sCmd: string; User: ItgUser);



Снимок сделан после выполнения строки:
Код: pascal
1.
rmethod := rtype.GetMethod(BotProcName);
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729786
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тут есть похожий пример
https://forum.antichat.ru/threads/362046/
но тут даже целый цикл запилили...
Ну ОК, я тоже сделал:
Код: pascal
1.
2.
3.
    for rmethod in rtype.GetMethods do
      if (rmethod.Parent = rtype) and (rmethod.Name = BotProcName) then
        rmethod.Invoke(Self, TArray<TValue>.Create(TValue.From<string>(AMessage.Text), TValue.From<string>(AMessage.From.ID.ToString)));


но вот что странно:



Видите, сработала бряка на строке 725, хотя:
rmethod.Name = 'Destroy', а BotProcName = 'PcmdStart'.
Как так?

Может, дело не в бабине?
...
Рейтинг: 0 / 0
Дженерики: передача процедуры в качестве параметра
    #39729854
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если метод не public или published то по умолчанию их в RTTI нет, вроде бы...
Из-за в System
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
{ RTTI Visibility }
type
  TVisibilityClasses = set of (vcPrivate, vcProtected, vcPublic, vcPublished);

const
  { These constants represent the default settings built into the compiler.
    For classes, these settings are normally inherited from TObject. }
  DefaultMethodRttiVisibility = [vcPublic, vcPublished];
  DefaultFieldRttiVisibility = [vcPrivate..vcPublished];
  DefaultPropertyRttiVisibility = [vcPublic, vcPublished];

type
  { Default RTTI settings }
  {$RTTI INHERIT
      METHODS(DefaultMethodRttiVisibility)
      FIELDS(DefaultFieldRttiVisibility)
      PROPERTIES(DefaultPropertyRttiVisibility)}



Укажите в том модуле где ваш класс с приватными методами
Код: pascal
1.
2.
{$RTTI INHERIT
      METHODS([vcPrivate, vcPublished])}


или
Код: pascal
1.
2.
{$RTTI EXPLICIT
      METHODS([vcPrivate, vcPublished])}


не помню что переопределяет...
...
Рейтинг: 0 / 0
25 сообщений из 108, страница 3 из 5
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Дженерики: передача процедуры в качестве параметра
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]