Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 2 [3] 4 5   вперед  Ctrl      все
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12484
X-Cite,

не это почти то же самое, только с использованием лямбла-функций?
31 окт 18, 09:31    [21719846]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12484
Valery_B
X11
Не смог найти.
Поэтому вопрос.
А есть ли у Delphi встроенный способ создать словарь с регистронезависимым (case-insensitive) поиском по ключам?
Или нужно самому пилить?


 FClassesList := TDictionary<string, TForm>.Create(TIStringComparer.Ordinal);


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

ок. наверное я где-то ещё обшибся.
спасибо
31 окт 18, 09:33    [21719848]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
Valery_B
Member

Откуда: Москва
Сообщений: 1810
X11
Valery_B
пропущено...


 FClassesList := TDictionary<string, TForm>.Create(TIStringComparer.Ordinal);


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


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;


К сообщению приложен файл. Размер - 21Kb
31 окт 18, 09:46    [21719860]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
zinpub
Member

Откуда:
Сообщений: 273


К сообщению приложен файл. Размер - 47Kb
31 окт 18, 09:54    [21719868]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
Valery_B
Member

Откуда: Москва
Сообщений: 1810
X11
Не понял... недавно использовал именно TIStringComparer.Ordinal и регистронезависимость не работала, а теперь работает

ок. наверное я где-то ещё обшибся.
спасибо

Ок.
По теме - не создавай функции/процедуры, а создавай классы.
Как было предложено ранее:
TBot  = class
...
end;
И их производные.
TSuperBot = class(TBot)
TKillerBot = class (TBot)

С таким кодом, будет гораздо проще работать и понимать.
Ты всегда можешь инициализировать класс так, как нужно тебе в конкретном случае.
31 окт 18, 09:57    [21719871]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12484
Valery_B, да верю, я верю, уже перепроверил и убедился, что ты прав.

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

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


Картинка с другого сайта.
31 окт 18, 09:57    [21719872]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12484
X11
Не понял... недавно использовал именно TIStringComparer.Ordinal и регистронезависимость не работала, а теперь работает


Вру. Скорей всего я "TIStringComparer.Ordinal" хотел использовать, но не использовал, т.к. полез в справку, а там написано, что - зависит от регистра.
31 окт 18, 09:59    [21719875]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
Valery_B
Member

Откуда: Москва
Сообщений: 1810
X11
Я не знаю, что не так у меня было в пенрвый раз, почему не сработало. Я именно с TIStringComparer.Ordinal и начинал.

Такое у всех было)
Потому что ты делал это в большом проекте, и тестировал не в тех местах.
31 окт 18, 09:59    [21719877]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
JaDi
Member

Откуда: Сызрань, Россия
Сообщений: 3862
Лол, чудаки из эмбы свою справку так и не исправили -- до сих пор стоит текст про регистрозависимость:
http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Generics.Defaults.TIStringComparer.Ordinal

Тогда как в коде там AnsiLowerCase используется (т.е. не зависит от регистра):
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;
31 окт 18, 10:05    [21719886]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
zinpub
Member

Откуда:
Сообщений: 273
JaDi,

Ха, прикольно... Ребята жгут
31 окт 18, 10:14    [21719900]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
white_nigger
Member

Откуда: Тула
Сообщений: 1933
Кстати, если правильно помню, то использование такого словаря приводило к утечке памяти в одной из версий делфи
31 окт 18, 12:08    [21720098]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
Василий 2
Member

Откуда:
Сообщений: 244
JaDi
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;

Неужели две конвертации строк и бинарное сравнение быстрее непосредственного сравнения без учета регистра?
1 ноя 18, 10:26    [21721160]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
zinpub
Member

Откуда:
Сообщений: 273
Василий 2,

А что такое "непосредственное сравнения без учета регистра" ?
1 ноя 18, 10:40    [21721190]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
Василий 2
Member

Откуда:
Сообщений: 244
zinpub
Василий 2,

А что такое "непосредственное сравнения без учета регистра" ?

AnsiCompare с параметром
1 ноя 18, 14:21    [21721538]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
zinpub
Member

Откуда:
Сообщений: 273
Василий 2,

Да так быстрее, но CompareString - на мой взгляд, несколько не подходит в данном случае, тк результат сравнения не всегда однозачен...
1 ноя 18, 14:38    [21721583]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12484
Немножко переделал. Теперь в словаре живут не ссылки процедуры, а строковые имена процедур.
Кто работал с RTTI, пожалуйста, подскажите, как выполнить метод по имени.
Читаю про TRttiContext, TRTTIType и TRTTIMethod примеры и справку, не могу врубиться.

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;

спасибо
7 ноя 18, 17:40    [21727184]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
Tactical Nuclear Penguin
Member

Откуда: холодно тут
Сообщений: 2594
rmethod.Invoke ?
7 ноя 18, 17:52    [21727195]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12484
вроде бы, но не разобрался как правильно ему передать параметры
7 ноя 18, 19:29    [21727297]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1164
rmethod.Invoke(Self, TArray<TValue>.Create(TValue.From<string>('AMessage.Text'), TValue.From<string>('AMessage.From')));

В вашем случае скорее всего так...
7 ноя 18, 20:36    [21727373]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1164
Ошибся выше, надо так:
rmethod.Invoke(Self, TArray<TValue>.Create(TValue.From<string>(AMessage.Text), TValue.From<string>(AMessage.From)));
7 ноя 18, 20:37    [21727376]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
Гирлионайльдо
Member

Откуда:
Сообщений: 286
Весело настанет когда, пользователь случайно, а может и не случайно используя уже какой - то метод, вызовет Invoke с типом объявленным посредством type тот же type myString = string и не сможет вызвать с этим аргументом
7 ноя 18, 22:46    [21727488]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12484
Гирлионайльдо, не понял...
8 ноя 18, 09:23    [21727705]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12484
Проблема в том, что
rmethod := rtype.GetMethod(BotProcName);

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

Картинка с другого сайта.

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


Снимок сделан после выполнения строки:
rmethod := rtype.GetMethod(BotProcName);
8 ноя 18, 09:32    [21727714]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 12484
тут есть похожий пример
https://forum.antichat.ru/threads/362046/
но тут даже целый цикл запилили...
Ну ОК, я тоже сделал:
    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'.
Как так?

Может, дело не в бабине?
8 ноя 18, 10:02    [21727758]     Ответить | Цитировать Сообщить модератору
 Re: Дженерики: передача процедуры в качестве параметра  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1164
Если метод не public или published то по умолчанию их в RTTI нет, вроде бы...
Из-за в System
{ 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)}


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

или
{$RTTI EXPLICIT
      METHODS([vcPrivate, vcPublished])}

не помню что переопределяет...
8 ноя 18, 11:49    [21727940]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 2 [3] 4 5   вперед  Ctrl      все
Все форумы / Delphi Ответить