español enum c# generics enums c#-7.3

español - return enum c#



C#7.3 Restricción de enumeración: ¿Por qué no puedo usar la palabra clave enum? (1)

Para restringir un parámetro de tipo genérico para que sea de un tipo de enumeración, anteriormente los restringí de esta manera, que era lo mejor que podía hacer para restringir el tipo T para las enumeraciones en pre-C # 7.3:

void DoSomething<T>() where T : struct, IComparable, IConvertible, IFormattable

Ahora, C # 7.3 agrega una nueva característica para restringir un tipo genérico a System.Enum . Intenté usar la restricción de enumeración con la actualización VS2017 15.7 lanzada hoy , y se compila correctamente cuando la escribo de esta manera (dado que tengo una directiva using System; ):

void DoSomething<T>() where T : Enum

Sin embargo, el uso de la palabra clave enum no funciona y hace que el compilador arroje los siguientes errores (hay más errores a continuación, se espera un cuerpo del método, pero realmente no vale la pena mencionarlo aquí, supongo):

void DoSomething<T>() where T : enum ^ error CS1031: Type expected error CS1002: ; expected ^ error CS1001: Identifier expected error CS1514: { expected error CS1513: } expected

Dado que hay una restricción de struct que funciona para las estructuras, no entiendo por qué la enum no funciona aquí para las enumeraciones. Es cierto que la enum no se asigna a un tipo real como lo haría int para Int32 , pero pensé que debería comportarse de la misma manera que la restricción de struct .

¿Acabo de caer en una trampa de características experimentales que aún no se ha implementado completamente, o fue hecho a propósito en la especificación (por qué)?


La restricción de struct en los genéricos no se asigna a un tipo real (aunque podría, en teoría, ValueType a ValueType ). De manera similar, la enum no se asigna limpiamente a los tipos reales de la misma manera que la string , int o long , establece una sintaxis especial para crear una clase de constantes simbólicas que se asignan a valores enteros; por lo tanto, public enum Stuff lugar de public class Stuff : Enum . Tenga en cuenta que si esto último se hubiera implementado en su lugar, sería más sutil, ya que cambiaría la sintaxis en función del tipo heredado, en lugar de cambiar la sintaxis en función de una palabra clave que no sea de class .

Entonces, en conclusión, sí, where T : enum no está destinado a funcionar porque enum es una palabra clave, no un alias de tipo. Si realmente quieres verlo funcionar porque enum al menos huele como un alias de tipo en contexto como estos, ¡pídelo!

EDITAR: Para alguna referencia histórica, aquí hay una pregunta de 2008 que indica que Enum no era una restricción válida, ya que es una clase especial.