Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Интересный вопрос про типы.


Страницы:   1 2

TrainerOfDolphins ©   (2006-09-20 12:18:00) 

Есть перечисляемый тип:
Type
TSomeType=(val1,val2,val3);
Вопрос:
Есть ли какой-нибудь способ быстро преобразовывать значения val1,val2,val3 в строки ‘val1’,’val2’,’val3’&
Ну скажем некая функция SomeTypeToStr (val: TSomeType):string…
Или только case val of придётся использовать?


TrainerOfDolphins   (2006-09-20 15:17:00) [1]


> begin
>  for v:=Low(TSomeType) to High(TSomeType) do
>  if v=val
>  then Result:=GetEnumName(TypeInfo(TCntrlsState),ord(v));
>
> end

Этот код уже не актуален. Смотри [21]


Anatoly Podgoretsky   (2006-09-20 15:15:00) [2]

На сообщение, что
begin
 for v:=Low(TSomeType) to High(TSomeType) do
 if v=val
 then Result:=GetEnumName(TypeInfo(TCntrlsState),ord(v));
end;

Result may be uninitialized - или что то подобное по смыслу.


TrainerOfDolphins   (2006-09-20 14:55:00) [3]

И что не правильно?


TrainerOfDolphins   (2006-09-20 14:53:00) [4]

На какое из сообщений Вы мне советуете обратить внимание? :)
Main.pas(958): Unsafe type 'PAnsiChar'
[Warning] Main.pas(960): Unsafe type 'PAnsiChar'
[Warning] Main.pas(1615): Unsafe code '@ operator'
[Warning] Main.pas(1615): Unsafe code '@ operator'


Anatoly Podgoretsky   (2006-09-20 14:46:00) [5]

Кстати компилятор должен был предупредить или мы сообщения не читаем или даже более того заблокировали их?


Anatoly Podgoretsky   (2006-09-20 14:45:00) [6]

TrainerOfDolphins ©   (20.09.06 14:31) [18]
И неправильно.


TrainerOfDolphins   (2006-09-20 14:43:00) [7]


> MBo ©   (20.09.06 14:36) [19]

Туплю... :)
Type
TSomeType=( val1,val2,val3);
function TSomeTypeToStr (val: TSomeType):string;
implementation
function TSomeTypeToStr (val: TSomeType):string;
begin
 Result:=GetEnumName(TypeInfo(TCntrlsState),ord(val));
end;
Ну тогда до неприличия просто...


TrainerOfDolphins   (2006-09-20 14:38:00) [8]

А теперь как сделать эту функцию универсальной для всех перечисляемых типов? По идее нужно передать в качестве параметра ещё и указатель  на тип. А как же быть тогда с определением типа переменных val i v? variant?
У меня пока ничего путнего не выходит...


MBo   (2006-09-20 14:36:00) [9]

>TrainerOfDolphins ©   (20.09.06 14:31) [18]
Зачем цикл и лишние проверки?


TrainerOfDolphins   (2006-09-20 14:31:00) [10]

В результате получилось очень даже не длинно:
Type
TSomeType=( val1,val2,val3);
function TSomeTypeToStr (val: TSomeType):string;
implementation
function TSomeTypeToStr (val: TSomeType):string;
var v: TSomeType;
begin
  for v:=Low(TSomeType) to High(TSomeType) do
  if v=val
  then Result:=GetEnumName(TypeInfo(TCntrlsState),ord(v));
end;


Anatoly Podgoretsky   (2006-09-20 14:10:00) [11]

TrainerOfDolphins ©   (20.09.06 12:54) [4]
Count := Type(High(Type)) - Ord(Low(Type)) + 1


TrainerOfDolphins   (2006-09-20 14:01:00) [12]

To StriderMan
> Но гораздо чаще нужно получить понятное название на русском
> языке.

Если для русских названий, то твой способ, спору нет, самый короткий. Короче, чем case of...


StriderMan   (2006-09-20 13:45:00) [13]


> TrainerOfDolphins ©   (20.09.06 13:42) [14]
> Но опять же, это нужно делать каждый раз. А основная положительная
> черта программера - лень...

на самом деле редко бывает необходимость получить имя перечисления как оно задано в коде. Разве что для лога. В таком случае конечно однозначно [1].

Но гораздо чаще нужно получить понятное название на русском языке.


TrainerOfDolphins   (2006-09-20 13:42:00) [14]

то StriderMan

> type
>  TSomeType = (st1, st2, ... stN);
>
> const
>  C_SOME_TYPE_NAMES: array[TSomeType] of string = ('st1,',
>  'st2', ... 'stN');
>
> далее понятно:
>  SomeName := C_SOME_TYPE_NAMES[stX];

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


TrainerOfDolphins   (2006-09-20 13:40:00) [15]

Пардон, я не оценил всей грациозности этой конструкции. Я определил i:integer, поэтому Делфи и ругалась...


StriderMan   (2006-09-20 13:37:00) [16]


> PZ   (20.09.06 12:59) [7]
> Я не считаю возможным оспаривать Вас, но мне кажется, что
> через "case val of" гораздо и гораздо проще.

я в таких случаях применяю такую конструкцию:

type
 TSomeType = (st1, st2, ... stN);

const
 C_SOME_TYPE_NAMES: array[TSomeType] of string = ('st1,', 'st2', ... 'stN');


далее понятно:
 SomeName := C_SOME_TYPE_NAMES[stX];


MBo   (2006-09-20 13:29:00) [17]

Ordinal types include integer, character, Boolean, enumerated, and subrange types, так что все работает (для Enumerated types with explicitly assigned ordinality, конечно, нехорошо будет)
Из давно работающего проекта:
 
type
TPaletteType = (ptGray, ptGrayInverse, ptRed, ptGreen, ptBlue, ptYellow,
   ptMagenta, ptAqua, ptBGR, ptQuasiBr, ptCustom);

class procedure TByteFrames.GetPalNames(Names: TStrings);
var
 i: TPaletteType;
begin
 Names.Clear;
 for i := Low(TPaletteType) to High(TPaletteType) do
   Names.Add(GetEnumName(TypeInfo(TPaletteType), Integer(i)));
end;


PZ   (2006-09-20 13:15:00) [18]

> [8] TrainerOfDolphins ©   (20.09.06 13:05)

Убедил


TrainerOfDolphins   (2006-09-20 13:11:00) [19]

то MBo

> for i := Low(TPaletteType) to High(TPaletteType) do begin

На это компилятор ругается. TSomeType - не порядковый тип, а перечисляемый, поэтому невозможно сказать что у него Low, а что High...


TrainerOfDolphins   (2006-09-20 13:05:00) [20]

to PZ
Но в этом случае придётся для каждого нового типа писать всё заново (хоть и не много). Настоящий нинзя программирования ничего не делает дважды... :)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо