![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Интересный вопрос про типы.
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
Но в этом случае придётся для каждого нового типа писать всё заново (хоть и не много). Настоящий нинзя программирования ничего не делает дважды... :)