Perché ottengo & # 8220; type non ha typeinfo & # 8221; errore con un tipo enum
Domanda
Ho dichiarato il seguente tipo di enum in cui voglio che il primo membro abbia il valore ordinale di 1 (uno) anziché il solito 0 (zero):
type
TMyEnum = (
meFirstValue = 1,
meSecondValue,
meThirdValue
);
Se chiamo TypeInfo () , ad es. come parte di una chiamata a GetEnumName () , viene visualizzato un errore del compilatore:
GetEnumName(TypeInfo(TMyEnum), Ord(aValue));
ERRORE: " E2134: il tipo 'TMyEnum' non ha typeinfo "
Perché questo?
So che le classi hanno typeinfo solo se sono compilate con l'opzione di compilatore $ M abilitata o (derivano da una classe che era, come TPersistent ) ma io non pensavo ci fossero condizioni speciali per avere typeinfo per i tipi enum.
Soluzione 2
Le informazioni sul tipo non sono supportate per gli enum in cui sono assegnati valori ordinali specifici che determinano membri enum con valori ordinali diversi da quelli che verrebbero assegnati dal compilatore.
Se valori specifici sono essenziali o desiderabili, "non utilizzato" i membri di enum dovranno essere inseriti in "pad" l'enum come richiesto. es. (rientro aggiuntivo solo per enfasi):
type
TMyEnum = (
meNOTUSED1, {= 0}
meFirstValue, {= 1}
meSecondValue,
meThirdValue
);
Un sottointervallo può quindi essere utilizzato per " filtro " il valore iniziale non utilizzato:
TValidMyEnum = meFirstValue..meThirdValue;
Anche se potresti voler prendere in considerazione la ridenominazione del tipo enum originale in modo che il tuo tipo subrange possa essere utilizzato in tutto il tuo progetto.
Un sottointervallo non è sufficiente se l'enum contiene " gap " ;:
type
TMyEnum = (
meNOTUSED1, {= 0}
meFirstValue, {= 1}
meSecondValue,
meThirdValue,
meNOTUSED2,
meFinalValue {= 5}
);
In questo caso non esiste semplicemente un modo per estendere il controllo dell'intervallo di tempo di compilazione per escludere i membri inutilizzati, ma un paio di tipi di set semplificheranno l'attività di implementazione dei controlli runtime necessari:
type
TMyEnums = set of TMyEnum;
const
meNOTUSED = [meUNUSED1, meUNUSED2]; // .. etc as required
meValidValues = [Low(TMyEnum)..High(TMyEnum)] - meNOTUSED;
if NOT (aValue in meValidValues) then
// etc
Altri suggerimenti
Le enumerazioni e le enumerazioni non contigue che non iniziano da zero non hanno typeinfo. Per essere implementato da typeinfo, dovrebbe essere in un formato diverso da quello esistente tkEnumeration, a causa di problemi di compatibilità con le versioni precedenti.
Ho preso in considerazione l'implementazione di un tkDiscontiguousEnumeration (o forse un membro con un nome migliore) per Delphi 2010, ma il vantaggio mi è sembrato piccolo considerando la loro relativa scarsità e le difficoltà di enumerazione: come si codificano gli intervalli in modo efficiente? Alcune codifiche sono migliori per alcuni scenari, peggio per altri.