Форум: "Начинающим";
Текущий архив: 2006.10.08;
Скачать: [xml.tar.bz2];
ВнизИнтересный вопрос про типы. Найти похожие ветки
← →
TrainerOfDolphins © (2006-09-20 12:18) [0]Есть перечисляемый тип:
Type
TSomeType=(val1,val2,val3);
Вопрос:
Есть ли какой-нибудь способ быстро преобразовывать значения val1,val2,val3 в строки ‘val1’,’val2’,’val3’&
Ну скажем некая функция SomeTypeToStr (val: TSomeType):string…
Или только case val of придётся использовать?
← →
MBo © (2006-09-20 12:20) [1]uses TypInfo
GetEnumName
← →
TrainerOfDolphins © (2006-09-20 12:35) [2]Спасибо. Это уже что-то. А есть такая же? только чтобы на входе был не номер значения, а само значение типа TSomeType?
← →
Игорь Шевченко © (2006-09-20 12:36) [3]
unit Test;
interface
{$M+}
type
TFooBar = (fbOne, fbTwo, fbThree, fbFour);
TFoo = class
private
FFooBar: TFooBar;
published
property FooBar : TFooBar read FFooBar write FFooBar;
end;
implementation
end.unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
TypInfo, Test;
{$R *.DFM}
function GetListEnumType(const T: Pointer): TStringList;
var
i: Byte;
EnumTypeData: PTypeData;
begin
// никакой обработки ошибок нет, сделано на скорую руку
Result := TStringList.Create;
EnumTypeData := GetTypeData(GetTypeData(PTypeInfo(T))^.BaseType^);
for i := EnumTypeData^.MinValue to EnumTypeData^.MaxValue do
Result.Add(GetEnumName(PTypeInfo(T), i))
end;
procedure TForm1.Button1Click(Sender: TObject);
var
PropInfo : PPropInfo;
begin
PropInfo := GetPropInfo(TFoo.ClassInfo, "FooBar");
ListBox1.Items.Assign(GetListEnumType(PropInfo^.PropType^));
end;
end.
← →
TrainerOfDolphins © (2006-09-20 12:54) [4]А как узнать количество значений перечисляемого типа?
← →
MBo © (2006-09-20 12:56) [5]>только чтобы на входе был не номер значения, а само значение типа TSomeType?
Используй Ord
← →
MBo © (2006-09-20 12:56) [6]for i := Low(TPaletteType) to High(TPaletteType) do begin
s := GetEnumName(TypeInfo(TPaletteType), Integer(i));
← →
PZ (2006-09-20 12:59) [7]> [3] Игорь Шевченко © (20.09.06 12:36)
Я не считаю возможным оспаривать Вас, но мне кажется, что через "case val of" гораздо и гораздо проще.
← →
TrainerOfDolphins © (2006-09-20 13:05) [8]to PZ
Но в этом случае придётся для каждого нового типа писать всё заново (хоть и не много). Настоящий нинзя программирования ничего не делает дважды... :)
← →
TrainerOfDolphins © (2006-09-20 13:11) [9]то MBo
> for i := Low(TPaletteType) to High(TPaletteType) do begin
На это компилятор ругается. TSomeType - не порядковый тип, а перечисляемый, поэтому невозможно сказать что у него Low, а что High...
← →
PZ (2006-09-20 13:15) [10]> [8] TrainerOfDolphins © (20.09.06 13:05)
Убедил
← →
MBo © (2006-09-20 13:29) [11]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;
← →
StriderMan © (2006-09-20 13:37) [12]
> 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];
← →
TrainerOfDolphins © (2006-09-20 13:40) [13]Пардон, я не оценил всей грациозности этой конструкции. Я определил i:integer, поэтому Делфи и ругалась...
← →
TrainerOfDolphins © (2006-09-20 13:42) [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];
Но опять же, это нужно делать каждый раз. А основная положительная черта программера - лень...
← →
StriderMan © (2006-09-20 13:45) [15]
> TrainerOfDolphins © (20.09.06 13:42) [14]
> Но опять же, это нужно делать каждый раз. А основная положительная
> черта программера - лень...
на самом деле редко бывает необходимость получить имя перечисления как оно задано в коде. Разве что для лога. В таком случае конечно однозначно [1].
Но гораздо чаще нужно получить понятное название на русском языке.
← →
TrainerOfDolphins © (2006-09-20 14:01) [16]To StriderMan
> Но гораздо чаще нужно получить понятное название на русском
> языке.
Если для русских названий, то твой способ, спору нет, самый короткий. Короче, чем case of...
← →
Anatoly Podgoretsky © (2006-09-20 14:10) [17]TrainerOfDolphins © (20.09.06 12:54) [4]
Count := Type(High(Type)) - Ord(Low(Type)) + 1
← →
TrainerOfDolphins © (2006-09-20 14:31) [18]В результате получилось очень даже не длинно:
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;
← →
MBo © (2006-09-20 14:36) [19]>TrainerOfDolphins © (20.09.06 14:31) [18]
Зачем цикл и лишние проверки?
← →
TrainerOfDolphins © (2006-09-20 14:38) [20]А теперь как сделать эту функцию универсальной для всех перечисляемых типов? По идее нужно передать в качестве параметра ещё и указатель на тип. А как же быть тогда с определением типа переменных val i v? variant?
У меня пока ничего путнего не выходит...
← →
TrainerOfDolphins © (2006-09-20 14:43) [21]
> 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;
Ну тогда до неприличия просто...
← →
Anatoly Podgoretsky © (2006-09-20 14:45) [22]TrainerOfDolphins © (20.09.06 14:31) [18]
И неправильно.
← →
Anatoly Podgoretsky © (2006-09-20 14:46) [23]Кстати компилятор должен был предупредить или мы сообщения не читаем или даже более того заблокировали их?
← →
TrainerOfDolphins © (2006-09-20 14:53) [24]На какое из сообщений Вы мне советуете обратить внимание? :)
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"
← →
TrainerOfDolphins © (2006-09-20 14:55) [25]И что не правильно?
← →
Anatoly Podgoretsky © (2006-09-20 15:15) [26]На сообщение, что
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 15:17) [27]
> begin
> for v:=Low(TSomeType) to High(TSomeType) do
> if v=val
> then Result:=GetEnumName(TypeInfo(TCntrlsState),ord(v));
>
> end
Этот код уже не актуален. Смотри [21]
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.10.08;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.045 c