powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Подскажите вариант CASE ... OF с условиями
25 сообщений из 58, страница 1 из 3
Подскажите вариант CASE ... OF с условиями
    #39796262
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На практике встречается длинная цепочка операторов: If () Then

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
if ( {условие-1} ) then begin {действия-1} end 
else
  if ( {условие-2} ) then begin {действия-2} end
  else
    if ({условие-3} ) then begin {действия-3} end
    else
      if ( {условие-4} ) then begin {действия-4} end 
      else
         // ...  и т.д. ОЧЕНЬ длинная конструкция 


Когда более 10 условий, то код становится трудно-читаемым.
К сожалению case () of здесь нельзя использовать, т.к. условия - вычисляемые.

Уважаемые гуру, как вы оформляете такой Delphi код?

Спасибо.
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796267
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Оформляй без сдвига
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
if ( {условие-1} ) then begin
  {действия-1} 
end else
if ( {условие-2} ) then begin 
  {действия-2}
end else
if ( {условие-3} ) then begin 
  {действия-3} 
end else
if ( {условие-4} ) then begin
 {действия-4}
end else
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796268
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1stт.к. условия - вычисляемые.
Например?
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796269
Фотография sasha27
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st,

Покажите результаты условия
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796273
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st,

Я не гуру, но как-то так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
if ( {условие-1} ) then begin 
  {действия-1} 

end else if ( {условие-2} ) then begin 
  {действия-2} 

end else if ( {условие-3} ) then begin 
  {действия-3} 

end else if ( {условие-4} ) then begin 
  {действия-4} 

end else if // ...  и т.д. ОЧЕНЬ длинная конструкция 
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796279
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanArtem.1stт.к. условия - вычисляемые.
Например?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
if ( ParamStr(0) = '/Help' ) then begin {действия-1} end 
else
  if ( ParamStr(0) = '/Start' ) then begin {действия-2} end
  else
    if (ParamStr(0) = '/Wait' ) then begin {действия-3} end
    else
      ....


Это абстрактный пример, а у меня все сложнее.
В help написано, что сase () of требует констатнты и только перечислимого типа, т.е. даже String нельзя использовать.

И как бороться с такими конструкциями?
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796283
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Artem.1st,

Ну если очень хочеться именно case .. of

то можно написать функцию приведения в которой будут те же if'ы
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796291
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Как-то так ...

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
type
  TMyParam = (mpHelp, mpStart, mpWait);
  
const 
  aMyParamTxt = array[mpHelp..mpWait] of string = ('/Help', '/Start', '/Wait'); 

...

function StrToMyParam(const iStr: string): TMyParam;
var
  aParam: TMyParam;
begin
  for aParam:= mpHelp to mpWait do
      if aMyParamTxt[aParam] = iStr then
	  begin
	    Result:= aParam;
		Exit;
	  end;
end;
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796292
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
case IndexStr(ParamStr(0), ['/Help', '/Start', '/Wait']) of 
  0: ; // Help
  1: ; // Start
  2: ; // Wait
end;
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796334
High.Programer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
zinpubКак-то так ...
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
type
  TMyParam = (mpHelp, mpStart, mpWait);
  
const 
  aMyParamTxt = array[mpHelp..mpWait] of string = ('/Help', '/Start', '/Wait'); 

...

function StrToMyParam(const iStr: string): TMyParam;
var
  aParam: TMyParam;
begin
  for aParam:= mpHelp to mpWait do
      if aMyParamTxt[aParam] = iStr then
	  begin
	    Result:= aParam;
		Exit;
	  end;
end;


Hint: "Result - может не вернуть значение."
ОК. Закроем на это глаза, но зачем 8(восемь) строк, когда достаточно всего 2(две) строки:
Код: pascal
1.
2.
3.
4.
5.
function StrToMyParam(const iStr: string): TMyParam;
begin
  for Result in mpHelp do
    if aMyParamTxt[Result] = iStr then Exit;
end;
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796338
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
High.Programer,

1. Ну это ж прототип...

2. Result после for не имеет гарантированного значения...
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796341
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
High.ProgramerОК. Закроем на это глаза, но зачем 8(восемь) строк, когда достаточно всего 2(две) строки:
Код: pascal
1.
2.
3.
4.
5.
function StrToMyParam(const iStr: string): TMyParam;
begin
  for Result in mpHelp do
    if aMyParamTxt[Result] = iStr then Exit;
end;


Надо ещё в конце (и в тип) добавить что-то вроде
Код: pascal
1.
Result := mpUnknown;

иначе может нежданчик случиться.
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796342
High.Programer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
выше была очепятка.
Оператор FOR...IN доступен с Delphi 2005:
Код: pascal
1.
2.
3.
4.
5.
function StrToMyParam(const iStr: string): TMyParam;
begin
  for Result in aMyParamTxt do
    if aMyParamTxt[Result] = iStr then Exit;
end;
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796349
High.Programer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
zinpub2. Result после for не имеет гарантированного значения...
Я не проверял, но помню, что это переменная цикла после индексного перебора For i:=0 to Count-1 do имеет неопределенное значения. А в нашем случае не индексный перебор, а последовательный(через энумератор)
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796352
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем велосипеды? IndexStr есть же.
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796360
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
High.Programer,

А какая разница? Что происходит с итератором - мало предсказуемо...
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796362
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
makhaonЗачем велосипеды? IndexStr есть же.

Для данного случая да, но если логика усложнится...
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796367
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
High.Programer ,
For..In использвоать боюсь, т.к. в детстве не приучили
:-)

zinpub, DimaBr ,
спасибо за идею. Проблема String для Case..OF решается, хотя для более сложных условий придется выстраивать многочисленные if then.
Похоже, не только в Delphi, я посмотрел в других языках C++, Java также "Switch" не помогает
:-(
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796403
mbb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
mbb
Гость
Как-то раз вот так сделал:

case Ord(<Усл1>) * 1 +
Ord(<Усл2>) * 2 +
Ord(<Усл3>) * 3
of
1:...
2:...
3;...
end;
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796448
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1stкак вы оформляете такой Delphi код?

Через список TList<TWorkerClass> или TObjectDictionary<string,TWorkerClass>
Код: pascal
1.
2.
3.
4.
5.
6.
7.
var
 Dict:ObjectDictionary<string,TWorkerClass>;
 s:string;
begin
 for s in Dict.Keys do 
  Dict[s].Work;
end;
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796488
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И зачем двойной доступ в Dictionary?


Код: pascal
1.
2.
3.
4.
5.
6.
7.
var
  Dict:ObjectDictionary<string,TWorkerClass>;
  Item: TPair<string,TWorkerClass>;
begin
  for Item in Dict do 
    Item.Value.Work;
end;
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796510
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Michael Longneck,

Тогда уж так.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
var
 Dict:ObjectDictionary<string,TWorkerClass>;
 Worker: TWorkerClass;
begin
 for Worker in Dict.Values do 
  Worker.Work;
end;
...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796616
Foxpc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Чё уж? Давайте пировать!

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
    InteractiveCallBack(ParamStr(0), 3,
    '/Help', procedure
      begin
        Writeln('Help');
      end,
    '/start', procedure
      begin
        Writeln('start');
      end,
    '/Wait', procedure
      begin
        Writeln('Wait');
      end);



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
unit InteractiveCallBackUnit;

interface

type
  TEventInteractiveNotify = Reference to procedure();

  InteractiveCallBackTmp2 = procedure(const Str1: string; Count: Integer; Name: string;
    E: TEventInteractiveNotify)Cdecl Varargs;

  TvaArgs = record
  const
    SizeAlign = SizeOf(NativeUint) - 1;
  private
    FPtr: PByte;
  public
    constructor Create(LastArg: Pointer; Size: Integer);
    function Read<T>(): T;
  end;

var
  InteractiveCallBack: InteractiveCallBackTmp2;

implementation

constructor TvaArgs.Create(LastArg: Pointer; Size: Integer);
begin
  FPtr := PByte(NativeUint(PByte(LastArg) + Size + SizeAlign) and not SizeAlign);
end;

function TvaArgs.Read<T>(): T;
begin
  Move(FPtr^, Result, SizeOf(T));
  FPtr := PByte(NativeUint(PByte(FPtr) + SizeOf(T) + SizeAlign) and not SizeAlign);
end;

procedure InteractiveCallBackTmp(const Str1: string; Count: Integer; Name: string;
  E: TEventInteractiveNotify); cdecl; // varargs;
var
  Va: TvaArgs;
  Str2: string;
  Event: Pointer;
begin
  Va := TvaArgs.Create(@Count, SizeOf(Integer));
  while Count >= 1 do
  begin
    Str2 := Va.Read<string>;
    Event := Va.Read<Pointer>;
    if Str1 = Str2 then
    begin
      TEventInteractiveNotify(Event)();
      Exit;
    end;
    Dec(Count);
  end;
end;

initialization

InteractiveCallBack := InteractiveCallBackTmp;

finalization

end.

...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796620
Foxpc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Под 64 битную платформу подправил
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
unit InteractiveCallBackUnit;

interface

type
  TEventInteractiveNotify = Reference to procedure();

  InteractiveCallBackTmp2 = procedure(const Str1: string; Count: Integer; Name: string;
    E: TEventInteractiveNotify)Cdecl Varargs;

  TvaArgs = record
  const
    SizeAlign = SizeOf(NativeUint) - 1;
  private
    FPtr: PByte;
  public
    constructor Create(LastArg: Pointer; Size: NativeUint);
    function Read<T>(): T;
  end;

var
  InteractiveCallBack: InteractiveCallBackTmp2;

implementation

constructor TvaArgs.Create(LastArg: Pointer; Size: NativeUint);
begin
  FPtr := PByte(NativeUint(PByte(LastArg) + Size + SizeAlign) and not SizeAlign);
end;

function TvaArgs.Read<T>(): T;
begin
  Move(FPtr^, Result, SizeOf(T));
  FPtr := PByte(NativeUint(PByte(FPtr) + SizeOf(T) + SizeAlign) and not SizeAlign);
end;

procedure InteractiveCallBackTmp(const Str1: string; Count: Integer; Name: string;
  E: TEventInteractiveNotify); cdecl; // varargs;
var
  Va: TvaArgs;
  Str2: string;
  Event: Pointer;
begin
  Va := TvaArgs.Create(@Count, SizeOf(NativeUint));
  while Count >= 1 do
  begin
    Str2 := Va.Read<string>;
    Event := Va.Read<Pointer>;
    if Str1 = Str2 then
    begin
      TEventInteractiveNotify(Event)();
      Exit;
    end;
    Dec(Count);
  end;
end;

initialization

InteractiveCallBack := InteractiveCallBackTmp;

finalization

end.

...
Рейтинг: 0 / 0
Подскажите вариант CASE ... OF с условиями
    #39796717
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1stНа практике встречается длинная цепочка операторов: If () Then

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
if ( {условие-1} ) then begin {действия-1} end 
else
  if ( {условие-2} ) then begin {действия-2} end
  else
    if ({условие-3} ) then begin {действия-3} end
    else
      if ( {условие-4} ) then begin {действия-4} end 
      else
         // ...  и т.д. ОЧЕНЬ длинная конструкция 


Уважаемые гуру, как вы оформляете такой Delphi код?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
if ( {условие-1} ) then
begin
  {действия-1} 
end
else if ( {условие-2} ) then
begin 
  {действия-2}
end
else if ( {условие-3} ) then
begin 
  {действия-3} 
end
else if ( {условие-4} ) then
begin
 {действия-4}
end
else
...



Либо, если позволяет код, вынести в подпрограмму, тогда:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
if ( {условие-1} ) then
begin
  {действия-1} 
  Exit;
end
if ( {условие-2} ) then
begin 
  {действия-2}
  Exit;
end
if ( {условие-3} ) then
begin 
  {действия-3} 
  Exit;
end
if ( {условие-4} ) then
begin
 {действия-4}
  Exit;
end
...



Либо, если не получается, обернуть в try-finally
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
try
if ( {условие-1} ) then
begin
  {действия-1} 
  Exit;
end
if ( {условие-2} ) then
begin 
  {действия-2}
  Exit;
end
if ( {условие-3} ) then
begin 
  {действия-3} 
  Exit;
end
if ( {условие-4} ) then
begin
 {действия-4}
  Exit;
end
...
finally
...выполнится для всех случаев
end;
...
Рейтинг: 0 / 0
25 сообщений из 58, страница 1 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Подскажите вариант CASE ... OF с условиями
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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