Delphi. Немного об использовании string в CASE

Автор: V.Krass. Опубликовано в Программирование . просмотров: 1489

Рейтинг:  4 / 5

Звезда активнаЗвезда активнаЗвезда активнаЗвезда активнаЗвезда не активна
 

Каждый разработчик для улучшения понимания кода программы, пытается повысить её читабельность. Один из вариантов это сделать - использовать оператор case при тестировании значения переменной. Но, к сожалению, в Delphi этот оператор умеет работать не со всеми типами переменных. Например, он не будет работать со строками. А что делать, если всё-таки нужно проверять переменную типа string оператором case? Давайте рассмотрим один из вариантов, как это можно сделать.

Тема сама по себе старая и известная, но, почему-то, она поднимается вновь и вновь. Кажется, достаточно открыть документацию к Delphi и увидеть, что там написано английским по "белому":

Case Statements

The case statement may provide a readable alternative to deeply nested if conditionals. A case statement has the form:

 

case selectorExpression of
  caseList1: statement1;
  ...
  caseListn: statementn;
end

where selectorExpression is any expression of an ordinal type smaller than 32 bits (string types and ordinals larger than 32 bits are invalid)

И всё становится ясным: string types are invalid! Ну, нельзя сделать CASE по string! И всё.

Однако....

Если припомнить, что основная задача оператора CASE - повышение читабельности кода программы. Что собственно и подтверждено в процитированном выше фрагменте HELP'а The case statement may provide a readable alternative to deeply nested if conditionals. И посмотреть на вопрос об использовании string в CASE уже с этой точки зрения, то возникает совсем другое дизайнерское решение!

И так, предположим, переменная типа string, которую хочется использовать в CASE, может принимать значения: 'english', 'deutsch', 'русский' или 'français'.

А раз, все строковые значения переменной можно перечислить, то почему бы не воспользоваться перечислимым типом для этого, ведь с перечислимым типом оператор CASE работает прекрасно:

type
  TStringSet = (english, deutsch, русский, français);

И смотрится оператор CASE в таком случае почти как "по string":

case ... of
  english : showmessage('выбрано english');
  deutsch : showmessage('выбрано deutsch');
  русский : showmessage('выбрано русский');
  français : showmessage('выбрано français');
  else
    showmessage('....');
end;

Остаётся лишь научиться находить элемент перечислимого типа, который по написанию совпадает со значением строковой переменной - фактически выполнить преобразование строки в элемент перечислимого типа, если такой, конечно, существует. Необходимый инструмент для этого находятся в unit TypInfo, а общая схема действий вырисовывается примерно следующая:

uses TypInfo;
type
  TStringSet = (english, deutsch, русский, français);
...
var
  StrVal : TStringSet;
  s : string
....
  s := 'русский';
  StrVal := TStringSet(GetEnumValue(TypeInfo(TStringSet), s ) );

Ну и "на десерт" остаётся добавить фрагмент работающего кода:

uses TypInfo;
type
  TStringSet = (english, deutsch, русский, français);
 
procedure UseCase(str : string);
var
  StrVal : TStringSet;
begin
  StrVal := TStringSet(GetEnumValue(TypeInfo(TStringSet), str));
  case StrVal of
    english : showmessage('выбрано english');
    deutsch : showmessage('выбрано deutsch');
    русский : showmessage('выбрано русский');
    français : showmessage('выбрано français');
    else
      showmessage('....');
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  UseCase('français');
end;

А все остальные нюансы и "специи" добавляются по вкусу.

Tags: Учебники по программированию Delphi

Добавить комментарий


Защитный код
Обновить