Utilizarea tipurilor delphi enumerate

Deci, ce este RTTI.
Informațiile de tip Runtime sau RTTI abreviate (informații despre tipurile de runtime) sunt datele generate de compilatorul Delphi despre obiectele programului. RTTI este o funcție de limbă care furnizează informații despre obiecte (nume, dimensiune instanță, indicii pentru clasa strămoșilor, nume de clasă etc.) și tipuri simple în timpul funcționării programului. Delphi, de exemplu, utilizează RTTI pentru a accesa valorile de proprietăți componente stocate și citite din fișierele dfm și care le afișează în Inspectorul de obiecte.






Definițiile tipului de bază, funcțiile de bază și procedurile pentru lucrul cu informațiile runtime sunt în modulul TypInfo. Acest modul conține două structuri fundamentale pentru a lucra cu RTTI - TTypeInfo și TTypeData (tipurile de indicatori de pe acestea sunt PTypeInfo și PTypeData, respectiv). Să încercăm să le folosim pe un exemplu concret.
Să presupunem că trebuie să generăm un șir de interogări aceluiași Google pentru a accesa API-ul. Ce putem învăța din documentația ClientLogin?
1. Astfel parametrii precum AccountType și Service pot lua valori foarte specifice, care pot fi reprezentate ca două tipuri de date enumerate:

tip TAccountType = (GOOGLE, Găzduit, HOSTED_OR_GOOGLE); tip TServices = (xapi, de analiză, aplicații, gbase, JotSpot, blogger, de imprimare, cl, codesearch, cp, Writely, finanțe, e-mail, sănătate, locale, LH2, annotateweb, înțelept , sitemap-uri, YouTube);

2. Răspunsul serverului poate conține, de asemenea, un număr limitat de erori (coduri) și o valoare ("Ok") la autentificarea cu succes. Prin urmare, primim un alt tip de date:

TErrorCodes tip = (Ok, BadAuthentication, NotVerified, TermsNotAgreed, CaptchaRequired, Necunoscut, AccountDeleted, AccountDisabled, ServiceDisabled, ServiceUnavailable);

Acum, că toate tipurile de date listate sunt definite, apare o întrebare simplă, "Ce urmează?". Ce vom face, de exemplu, atunci când creăm un șir de interogare, dacă absolut nimic nu știa despre RTTI și, în special, modulul TypInfo?






Cel puțin, vom organiza ceva de genul:

var Param: șir; AccType: TAccountType; începe cazul AccType de GOOGLE: ParamStr: = 'Ceva acolo-AccauntType = GOOGLE'; HOSTED: ParamStr: = 'ceva acolo - AccauntType = HOSTED'; HOSTED_OR_GOOGLE: ParamStr: = 'Ceva acolo - AccauntType = HOSTED_OR_GOOGLE'; se încheie; se încheie;

Aproximativ același lucru este valabil și pentru serviciile TS. Va funcționa acest cod? Bineînțeles ... unde va merge? Dar poți să o faci diferit.
Următoarea metodă este definită în modulul TypInfo:

funcția GetEnumName (TypeInfo: PTypeInfo; Valoare: Integer): șir;

Returnează valoarea tipului enumerat ca un șir simplu. Primul parametru este un indicator pentru înregistrarea TTypeInfo. al doilea este numărul de secvență al valorii din tipul de date enumerat.
Aceasta este, executând următorul cod:

Vom primi un mesaj care conține șirul "HOSTED". Aplicând această metodă, putem reduce codul reprezentat mai sus la o singură linie:

var Param: șir; AccType: TAccountType; începe ParamStr: = 'ceva acolo-AccountType =' + GetEnumName (TypeInfo (TAccountType), ord (AccType)); se încheie;

Sau, dacă utilizați un șablon pentru a forma un șir, atunci:

var Param: șir; AccType: TAccountType; începeți ParamStr: = Format (Shablon, [GetEnumName (TypeInfo (TAccountType), ord (AccType)]);

Acum, să spunem că am generat un șir de interogări, am trimis o solicitare serverului și am primit un răspuns care conține un cod "OK" sau un cod de eroare șir. Și avem nevoie de o anumită variabilă de tip TErrorCodes pentru a atribui o valoare în funcție de răspuns. Din nou, cum am putea face fără cunoașterea lui TypInfo, având, de exemplu, codul de eroare "NotVerified"? Cineva a început să picteze un buchet if..then..else, sau de a folosi AnsiIndexStr metoda modulului StrUtils pentru a compara apoi valoarea rezultată cu valoarea de tipul de comandă astfel:

var ErrCode: Coduri TError; începe ErrCode: = Coduri TError (AnsiIndesStr (MassivStrok, "NotVerified"))); se încheie;

Din nou, totul va funcționa, dar de ce ar trebui să tragem modulul suplimentar StrUtils în utilizări când deja avem TypInfo? Să folosim încă o metodă pentru a lucra cu tipurile enumerate:

funcția GetEnumValue (TypeInfo: PTypeInfo; const Nume: șir): Integer;

Metoda returnează numărul de ordine al valorii tipului enumerat. Intrarea este tot același indicator pentru TTypeInfo și valoarea tipului ordinal ca șir. Doar ceea ce avem nevoie. Ca urmare a utilizării GetEnumValue, fragmentul de cod de mai sus poate fi reprezentat după cum urmează:

08/05/02
UPDATE: un mic plus - funcția GetEnumValue și GetEnumName nu arunca excepții în cazuri, dacă setați al doilea rând incorect parametru sau nu există un index de element. În primul caz, GetEnumValue va returna pur și simplu o valoare de 255, iar GetEnumName un șir incomprehensibil.

UPDATE. În cazul în care elementele de tip enumerate nu încep cu 0 normal și, de exemplu 3, obținem la compilare eroare «EROARE:«E2134: Tipul «TMyEnum» nu are nici o typeinfo»»







Articole similare

Trimiteți-le prietenilor: