Показать сообщение отдельно
  #4  
Старый 09.01.2017, 20:24
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

можно высчитать, можно просто функцию попроще использовать:
Код:
function MyCalcHash(a, b : byte) : Integer;
begin
   Result := a*1000 + b;
end;
результат:
Код:
MyCalcHash(1,1) = 1001
MyCalcHash(10,8) = 10008
и т.д.

А вообще, я бы подумал над динамическим выполением этого условия.
Все, конечно, зависит от того, что конкретно надо делать в зависимости от значений a & b. Если просто присвоить значение какой-нить переменной или вызвать СТАНДАРТНУЮ функцию, то городить огород смыла нет. А вот если надо выполнить свой код, причем довольно объемный, да еще и в программе этот case при стандартном сценарии использования исполняется многократно, то тогда можно заморочиться с более динамической штукой.
Как сделать:
1. Пишем базовый класс:
Код:
interface

type
  TDynamicActionBase = class
  protected
    procedure DoExecute; virtual; abstract;
    function CanExecute(a, b : byte) : Boolean; virtual; abstract;
  public
    function Execute(a, b : byte): Boolean;
    procedure Register(AList : TObjectList);
  end;

implementation

procedure TDynamicActionBase.Register(AList : TObjectList);
begin
  AList.Add(Self);
end;

function TDynamicActionBase.Execute(a, b : Byte) : Boolean;
begin
  Result := CanExecute(a,b);
  If Result Then DoExecute;
end;

2. Теперь для каждого реального действия "рожаем" наследника и перекрываем у него соотв. методы:
Код:
interface

type
  TDynamicAction_1_1 = class(TDynamicActionBase)
  protected
    procedure DoExecute; override;
    function CanExecute(a, b : byte) : Boolean; override;
  end;

  TDynamicAction_2_2 = class(TDynamicActionBase)
  protected
    procedure DoExecute; override;
    function CanExecute(a, b : byte) : Boolean; override;
  end;

implementation

procedure TDynamicAction_1_1.DoExecute;
begin
  ShowMessage('1-1'); // Просто для демонстрации
end;

function TDynamicAction_1_1.CanExecute(a, b : byte) : Boolean;
begin
  Result := (a = 1) and (b = 1);
end;

procedure TDynamicAction_2_2.DoExecute;
begin
  ShowMessage('2-2'); // Просто для демонстрации
end;

function TDynamicAction_2_2.CanExecute(a, b : byte) : Boolean;
begin
  Result := (a = 2) and (b = 2);
end;

3. Теперь нам надо наши классы зарегистрировать в списке:
Код:
interface

var
  DynamicActionList : TObjectList;

initialization
  DynamicActionList := TObjectList.Create(True);
  TDynamicAction_1_1.Create.Register(DynamicActionList);
  TDynamicAction_2_2.Create.Register(DynamicActionList);

finalization
  FreeAndNil(DynamicActionList);

end.

4. Ну и последний штрих. Надо написать процедуру-выполнятель (функцию, если ничего не нашлось, то она вернет False, если что-то нашлось - то True)
Код:
interface

function ExecuteDynamicAction(a,b : byte) : Boolean;

implementation

function ExecuteDynamicAction(a,b : byte) : Boolean;
var
  I : Integer;
begin
  Result := False;
  For I := 0 To DynamicActionList.Count-1 Do
    begin
      Result := (DynamicActionList[i] As TDynamicActionBase).Execute(a,b);
      If Result Then Break;
    end;
end;
Это вариант, когда надо выполнять только одно, первое зарегистрированное, действие. Можно переделать, что бы можно было регистрировать несколько действий на одну комбинацию...

ЗЫ. Если хочется действия развести по разным модулям, то тогда прямое обращение к списку действий надо заменить на использование фабрики, а описание DynamicActionList перенести в секцию implementation. DynamicActionList д.б. синглтоном.
Ответить с цитированием