Question

J'ai déclaré le type enum suivant dans lequel je souhaite que le premier membre ait la valeur ordinale 1 (un) plutôt que le 0 (zéro) habituel:

  type
    TMyEnum = (
               meFirstValue = 1,
               meSecondValue,
               meThirdValue
              );

Si j'appelle TypeInfo () , par exemple. dans le cadre d'un appel à GetEnumName () , une erreur de compilation est générée:

  GetEnumName(TypeInfo(TMyEnum), Ord(aValue));

ERREUR: "E2134: Le type 'TMyEnum' n'a pas de typeinfo" "

.

Pourquoi est-ce?

Je sais que les classes n'ont de typeinfo que si elles sont compilées avec l'option de compilateur $ M activée ou (dériver d'une classe qui était telle que TPersistent ), mais je ne pensais pas qu'il y avait des conditions spéciales pour avoir typeinfo pour les types enum.

Était-ce utile?

La solution 2

Les informations de type ne sont pas prises en charge pour les énumérations où des valeurs ordinales spécifiques sont attribuées. Ainsi, les membres de énumération ont des valeurs ordinales différentes de celles qui seraient normalement attribuées par le compilateur.

Si des valeurs spécifiques sont essentielles ou souhaitables, " non utilisé " les membres enum devront être insérés dans & pad; pad " l'énum comme requis. Par exemple (indentation supplémentaire pour l'emphase seulement):

  type
    TMyEnum = (
                meNOTUSED1,   {= 0}
               meFirstValue,  {= 1} 
               meSecondValue,
               meThirdValue
              );

Une sous-gamme peut ensuite être utilisée pour "filtrer" la valeur initiale non utilisée:

   TValidMyEnum = meFirstValue..meThirdValue;

Bien que vous souhaitiez peut-être alors envisager de renommer le type enum d'origine afin que votre type de sous-gamme puisse être utilisé dans tout votre projet.

Une sous-gamme ne suffit pas si l'énumération contient des "espaces":

  type
    TMyEnum = (
                meNOTUSED1,   {= 0}
               meFirstValue,  {= 1} 
               meSecondValue,
               meThirdValue,
                meNOTUSED2,
               meFinalValue   {= 5}
              );

Dans ce cas, il n’existe pas de moyen simple d’étendre la vérification de la plage de compilation pour exclure les membres inutilisés, mais quelques types d’ensembles simplifieront la mise en œuvre des vérifications d’exécution nécessaires:

  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

Autres conseils

Les énumérations non contiguës et les énumérations qui ne commencent pas à zéro n'ont pas typeinfo. Pour que typeinfo soit implémenté, il devrait être dans un format différent de tkEnumeration existant, en raison de problèmes de compatibilité avec les versions antérieures.

J'ai envisagé de mettre en œuvre une énumération tkDiscontiguous (ou peut-être un meilleur nom) pour Delphi 2010, mais l'avantage semblait minime compte tenu de leur rareté relative et des difficultés d'énumération. Comment coder efficacement les plages? Certains encodages sont meilleurs pour certains scénarios et pires pour d'autres.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top