¿Por qué aparece el error "tipo no tiene información de tipo" con un tipo de enumeración

StackOverflow https://stackoverflow.com/questions/1420562

  •  07-07-2019
  •  | 
  •  

Pregunta

He declarado el siguiente tipo de enumeración en el que quiero que el primer miembro tenga el valor ordinal de 1 (uno) en lugar del 0 (cero) habitual:

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

Si llamo a TypeInfo () , p. Como parte de una llamada a GetEnumName () , recibo un error del compilador:

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

ERROR: " E2134: El tipo 'TMyEnum' no tiene typeinfo "

¿Por qué es esto?

Sé que las clases solo tienen información de tipo si se compilan con la opción del compilador $ M habilitada o (derivan de alguna clase que era, como TPersistent ) pero yo no creía que hubiera condiciones especiales para tener typeinfo para tipos de enumeración.

¿Fue útil?

Solución 2

La información de tipo no es compatible con las enumeraciones en las que se asignan valores ordinales específicos que dan como resultado que los miembros de la enumeración tengan valores ordinales diferentes a los que el compilador asignaría normalmente.

Si los valores específicos son esenciales o deseables, "no utilizado" los miembros de enumeración deberán insertarse en " pad " la enumeración según sea necesario. por ejemplo (sangría adicional solo para énfasis):

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

Se puede usar un subrango para filtrar " el valor inicial no utilizado:

   TValidMyEnum = meFirstValue..meThirdValue;

Aunque es posible que desee considerar cambiar el nombre del tipo de enumeración original para que su tipo de subrango se pueda utilizar en todo su proyecto.

Un subrango no es suficiente si la enumeración contiene '' espacios '':

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

En este caso, no existe una forma simple de extender la verificación del rango de tiempo de compilación para excluir a los miembros no utilizados, pero un par de tipos de conjunto simplificará el negocio de implementar cualquier verificación necesaria de tiempo de ejecución :

  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

Otros consejos

Las enumeraciones no contiguas y las enumeraciones que no comienzan en cero no tienen typeinfo. Para que typeinfo se implemente, necesitaría estar en un formato diferente del tkEnumeration existente, debido a problemas de compatibilidad con versiones anteriores.

Pensé en implementar una enumeración tkDiscontiguous (o posiblemente un miembro mejor nombrado) para Delphi 2010, pero el beneficio parecía pequeño teniendo en cuenta su escasez relativa y las dificultades en la enumeración: ¿cómo codifica los rangos de manera eficiente? Algunas codificaciones son mejores para algunos escenarios, peores para otros.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top