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.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top