respuesta corta, sí. En este caso específico, es posible que desee considerar el uso deTimeSpan
Jodrell
1
Usar métodos de extensión en una enumeración me haría sentir sucio. Crea una clase para encapsular lo que se necesita. Mantenga una enumeración lo más simple posible. Si necesita más lógica asociada con él, cree una clase de Duración que exponga el día, la semana, el mes y contenga cualquier otra lógica que hubiera estado en el método de extensión.
Jason Evans
2
Me gusta tener métodos de extensión de enumeración para grupos de banderas. Prefiero las cláusulas if, por ejemplo, Day.IsWorkday()en lugar (Day & Days.Workday) > 0de Days.Workdaydefinidas como Monday | Tuesday ... | Friday. El primero es más claro en mi opinión y tiene exactamente el segundo implementado.
Los métodos de extensión proporcionan una forma de escribir métodos para clases existentes de una manera que otras personas de su equipo podrían descubrir y utilizar. Dado que las enumeraciones son clases como cualquier otra, no debería ser demasiado sorprendente que pueda extenderlas, como:
Creo que las enumeraciones no son la mejor opción en general, pero al menos esto te permite centralizar algunos de los cambios / if manipularlos y abstraerlos un poco hasta que puedas hacer algo mejor. Recuerde verificar que los valores también estén dentro del rango.
Creo que el comentario de "las enumeraciones son malas" está fuera de lugar pero tiene una base en la realidad. Encuentro que las enumeraciones pueden ser un problema si se usan en exceso, ya que de alguna manera te encierran en ciertos contextos y comportamientos.
Ed Schwehm
1
Enumeraciones en C # tipo de chupar, porque esto puede compilar y ejecutar:Duration d = 0;
Graham
16
Given that enums are classesno, no son clases.
Winger Sendon
1
Utilizo este tipo de extensión solo si se trata directamente de la enumeración, como los días de la semana y los métodos de extensión IsWeekday (), IsWeekendday (). Pero las clases están destinadas a encapsular comportamientos, por lo que si hay muchos comportamientos complicados que encapsular, una clase probablemente sea mejor. Si es limitado y básico, personalmente encuentro bien las extensiones en enumeraciones. Como ocurre con la mayoría de las decisiones de diseño, existen límites difusos entre las opciones (IMO). Vale la pena señalar que las extensiones solo se pueden realizar en clases estáticas de nivel superior, no en clases anidadas. Si tu enumeración es parte de una clase, necesitarás hacer una clase.
FreeText
51
También puede agregar un método de extensión al tipo Enum en lugar de una instancia de Enum:
/// <summary> Enum Extension Methods </summary>/// <typeparam name="T"> type of Enum </typeparam>publicclassEnum<T>where T :struct,IConvertible{publicstaticintCount{get{if(!typeof(T).IsEnum)thrownewArgumentException("T must be an enumerated type");returnEnum.GetNames(typeof(T)).Length;}}}
Puede invocar el método de extensión anterior haciendo:
var result =Enum<Duration>.Count;
No es un verdadero método de extensión. Solo funciona porque Enum <> es de un tipo diferente a System.Enum.
¿Puede la clase staticasegurarse de que todos sus métodos se comporten como extensiones?
Jatin Sanghvi
15
Para futuros lectores: la ambigüedad del nombre de Enum<T>es un poco confusa. También se podría llamar a EnumUtils<T>la clase y la llamada al método se resolvería en EnumUtils<Duration>.Count.
Namoshek
46
Por supuesto que puede, digamos, por ejemplo, que desea utilizar DescriptionAttribueen sus enumvalores:
using System.ComponentModel.DataAnnotations;publicenumDuration{[Description("Eight hours")]Day,[Description("Five days")]Week,[Description("Twenty-one days")]Month}
Ahora quieres poder hacer algo como:
Duration duration =Duration.Week;var description = duration.GetDescription();// will return "Five days"
Su método de extensión GetDescription()se puede escribir de la siguiente manera:
using System.ComponentModel;
using System.Reflection;publicstaticstringGetDescription(thisEnumvalue){FieldInfo fieldInfo =value.GetType().GetField(value.ToString());if(fieldInfo ==null)returnnull;var attribute =(DescriptionAttribute)fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute));return attribute.Description;}
Estaba buscando crear una extensión para casi exactamente lo que hizo la muestra, excepto mi uso DisplayAttribute Localized GetDescription. saludos
George
Esta es una buena alternativa, aunque creo que el espacio de nombres es solo System.ComponentModel?
TomDestry
Buena perspectiva y gracias por mostrar la implementación y el código de extensión. Para acumular: con su implementación, también puede llamarlo así: var description = Duration.Week.GetDescription ();
Spencer Sullivan
31
Todas las respuestas son geniales, pero están hablando de agregar un método de extensión a un tipo específico de enumeración.
¿Qué sucede si desea agregar un método a todas las enumeraciones, como devolver un int del valor actual en lugar de la conversión explícita?
publicstaticclassEnumExtensions{publicstaticintToInt<T>(this T soure)where T :IConvertible//enum{if(!typeof(T).IsEnum)thrownewArgumentException("T must be an enumerated type");return(int)(IConvertible) soure;}//ShawnFeatherly funtion (above answer) but as extention methodpublicstaticintCount<T>(this T soure)where T :IConvertible//enum{if(!typeof(T).IsEnum)thrownewArgumentException("T must be an enumerated type");returnEnum.GetNames(typeof(T)).Length;}}
El truco detrás IConvertiblees su jerarquía de herencia ver MDSN
Ídem. Funciona si llamo a la extensión directamente (por ejemplo MyExtention.DoThing(myvalue)) pero en realidad no se adjunta a la enumeración (por ejemplo myvalue.DoThing())
Sinaesthetic
1
FYI, C # 7.3 ahora admite Enum como una restricción de tipo genérico
redtetrahedron
7
Puede crear una extensión para cualquier cosa, incluso object(aunque eso no se considera una práctica recomendada ). Comprenda un método de extensión solo como un public staticmétodo. Puede utilizar el tipo de parámetro que desee en los métodos.
Un voidvalor de retorno en una enumeración es algo extraño. Pensaría en una muestra más realista.
psubsee2003
3
@ psubsee2003 ¿el OP seguramente tiene suficiente conocimiento para cambiar esto para satisfacer sus necesidades? ¿Por qué es importante la muestra? Basta con responder a la pregunta inicial.
LukeHennerley
3
¿Soy el único que encuentra raros los ejemplos de código en MSDN? ¡La mayoría de las veces necesitas un esfuerzo real para comprender lo que están tratando de hacer!
TimeSpan
Day.IsWorkday()
en lugar(Day & Days.Workday) > 0
deDays.Workday
definidas comoMonday | Tuesday ... | Friday
. El primero es más claro en mi opinión y tiene exactamente el segundo implementado.Respuestas:
Según este sitio :
Los métodos de extensión proporcionan una forma de escribir métodos para clases existentes de una manera que otras personas de su equipo podrían descubrir y utilizar. Dado que las enumeraciones son clases como cualquier otra, no debería ser demasiado sorprendente que pueda extenderlas, como:
Creo que las enumeraciones no son la mejor opción en general, pero al menos esto te permite centralizar algunos de los cambios / if manipularlos y abstraerlos un poco hasta que puedas hacer algo mejor. Recuerde verificar que los valores también estén dentro del rango.
Puede leer más aquí en Microsft MSDN.
fuente
Duration d = 0;
Given that enums are classes
no, no son clases.También puede agregar un método de extensión al tipo Enum en lugar de una instancia de Enum:
Puede invocar el método de extensión anterior haciendo:
No es un verdadero método de extensión. Solo funciona porque Enum <> es de un tipo diferente a System.Enum.
fuente
static
asegurarse de que todos sus métodos se comporten como extensiones?Enum<T>
es un poco confusa. También se podría llamar aEnumUtils<T>
la clase y la llamada al método se resolvería enEnumUtils<Duration>.Count
.Por supuesto que puede, digamos, por ejemplo, que desea utilizar
DescriptionAttribue
en susenum
valores:Ahora quieres poder hacer algo como:
Su método de extensión
GetDescription()
se puede escribir de la siguiente manera:fuente
Todas las respuestas son geniales, pero están hablando de agregar un método de extensión a un tipo específico de enumeración.
¿Qué sucede si desea agregar un método a todas las enumeraciones, como devolver un int del valor actual en lugar de la conversión explícita?
El truco detrás
IConvertible
es su jerarquía de herencia ver MDSNGracias a ShawnFeatherly por su respuesta.
fuente
MyExtention.DoThing(myvalue)
) pero en realidad no se adjunta a la enumeración (por ejemplomyvalue.DoThing()
)Puede crear una extensión para cualquier cosa, incluso
object
(aunque eso no se considera una práctica recomendada ). Comprenda un método de extensión solo como unpublic static
método. Puede utilizar el tipo de parámetro que desee en los métodos.fuente
Consulte MSDN .
fuente
void
valor de retorno en una enumeración es algo extraño. Pensaría en una muestra más realista.acabamos de hacer una extensión de enumeración para c # https://github.com/simonmau/enum_ext
Es solo una implementación para typesafeenum, pero funciona muy bien, así que creamos un paquete para compartir, diviértete con él
Sé que el ejemplo es algo inútil, pero entiendes la idea;)
fuente
Una solución alternativa sencilla.
fuente