Pregunta

Para permitir diferentes opciones de formato en un método que muestra una noticia, he creado una enumeración que se puede pasar para especificar cómo se muestra.

[Flags]
private enum NewsStyle
{
    Thumbnail = 0,
    Date = 1,
    Text = 2,
    Link = 4,
    All = 8
}

string FormatNews( DataRow news, NewsStyle style )
{
    StringBuilder HTML = new StringBuilder();

    // Should the link be shown
    if ( ((newsStyle & NewsStyle.All) == NewsStyle.All || (newsStyle & NewsStyle.Link) == NewsStyle.Link))
    {
                HTML.AppendFormat("<a style=\"text-decoration:none; color: rgb(66, 110, 171);\" href=\"ViewStory.aspx?nsid={0}\">",
                                  UrlEncode(newsStory["NewsStoryID"].ToString()));
    }

    // Etc etc...
}

// So to call the method...
Response.Write( FormatNews( news, NewsStyle.Date | NewsStyle.Text ) );

El problema es que solo puedo hacer que el código funcione si especifico manualmente los valores en la enumeración, de lo contrario, la operación de comprobación de enumeración a nivel de bits no funcionará correctamente.

Siempre he seguido la regla de dejar que .net maneje la asignación de valores a las enumeraciones. ¿Es esta una excepción excepcional?

¿Fue útil?

Solución

Sí, es una excepción genuina. Las enumeraciones son valores asignados por defecto de 0 en adelante, cada uno 1 más alto que el valor anterior, independientemente de cualquier FlagsAttribute s. (Por supuesto, hay reglas más elaboradas para cuando se especifican algunos valores manualmente; consulte documentos de MSDN )

Si bien en cierto modo tiene sentido tener una enumeración de banderas para obtener valores en poder de dos, veo razones por las que probablemente es mejor no hacerlo:

Es perfectamente razonable tener una enumeración como esta:

[Flags]
enum Foo
{
    None,
    Bar,
    Baz, 
    BarAndBaz
} 

Esto, por supuesto, requiere que los valores sean 0, 1, 2 y 3 para ser sensibles.

Sería bastante contraintuitivo dejar que la presencia de un mero atributo cambie el significado completo de una pieza de código C #. Considera mi enumeración de ejemplo Foo . ¿Debería permitirse que la eliminación del atributo Flags rompa el código cambiando silenciosamente los valores del enumerador?

Otros consejos

Sí, debe especificar los valores en Enum para que los valores de indicador agregados funcionen correctamente (para poder combinar dos indicadores de enumeración y no tener ese valor de conflicto con otro indicador especificado). No es necesario que especifique valores para compilarlo, pero es probable que el resultado no sea el que está buscando.

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