Каждый разработчик для улучшения понимания кода программы, пытается повысить её читабельность. Один из вариантов это сделать — использовать оператор case при тестировании значения переменной. Но, к сожалению, в Delphi этот оператор умеет работать не со всеми типами переменных. Например, он не будет работать со строками. А что делать, если всё-таки нужно проверять переменную типа string оператором case? Давайте рассмотрим один из вариантов, как это можно сделать.
Тема сама по себе старая и известная, но, почему-то, она поднимается вновь и вновь. Кажется, достаточно открыть документацию к Delphi и увидеть, что там написано английским по «белому»:
Case StatementsThe 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;endwhere 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 работает прекрасно:
1 2 |
type TStringSet = (english, deutsch, русский, français); |
И смотрится оператор CASE в таком случае почти как «по string»:
1 2 3 4 5 6 7 8 |
case ... of english : showmessage('выбрано english'); deutsch : showmessage('выбрано deutsch'); русский : showmessage('выбрано русский'); français : showmessage('выбрано français'); else showmessage('....'); end; |
Остаётся лишь научиться находить элемент перечислимого типа, который по написанию совпадает со значением строковой переменной — фактически выполнить преобразование строки в элемент перечислимого типа, если такой, конечно, существует. Необходимый инструмент для этого находятся в unit TypInfo, а общая схема действий вырисовывается примерно следующая:
1 2 3 4 5 6 7 8 9 10 |
uses TypInfo; type TStringSet = (english, deutsch, русский, français); ... var StrVal : TStringSet; s : string .... s := 'русский'; StrVal := TStringSet(GetEnumValue(TypeInfo(TStringSet), s ) ); |
Ну и «на десерт» остаётся добавить фрагмент работающего кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
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; |
А все остальные нюансы и «специи» добавляются по вкусу.
Ваш комментарий будет первым