Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1158512443
ec_stasis
2006-09-17 21:00
2006.10.08
Поменять длину массива


6-1146944800
Satanist
2006-05-06 23:46
2006.10.08
Словить сlick в WebBrowser


2-1158344853
Vovan#1
2006-09-15 22:27
2006.10.08
Про DLL и строки.


15-1158600999
Весь в делах
2006-09-18 21:36
2006.10.08
Фашисты опять лезут власть


2-1158488661
linox
2006-09-17 14:24
2006.10.08
с listview в файл?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский