usar valores decimales como parámetros de atributo en c #?


81

He intentado usar valores decimales como parámetros para un atributo de campo, pero obtengo un error del compilador.

Encontré este enlace de publicación de blog diciendo que no era posible usar .NET en ese momento, ¿alguien sabe por qué eligen esto o cómo puedo usar parámetros decimales?


Respuestas:


121

Esta es una restricción de CLR. Sólo las constantes primitivas o las matrices de primitivas pueden utilizarse como parámetros de atributo. La razón es que un atributo debe estar codificado completamente en metadatos. Esto es diferente al cuerpo de un método que está codificado en IL. El uso de metadatos solo restringe severamente el alcance de los valores que se pueden usar. En la versión actual de CLR, los valores de metadatos se limitan a primitivas, nulos, tipos y matrices de primitivas (es posible que se hayan perdido una menor).

Los decimales, mientras que un tipo básico no son un tipo primitivo y, por lo tanto, no se pueden representar en metadatos, lo que evita que sea un parámetro de atributo.


5
¿Sigue siendo un problema con Framework 4.0? y 4.5, 4.6.x?
midspace

@midspace, no es realmente un problema, solo una limitación, impuesta por el diseño. Es lamentable, pero hay muchas posibilidades de que nunca desaparezca.
Bruno Brant

1
"Solo las constantes primitivas o las matrices de primitivas pueden utilizarse como parámetros de atributo". No parece ser exactamente cierto, por ejemplo, System.Type también está permitido: msdn.microsoft.com/en-us/library/aa664615(v=vs.71).aspx
DixonD

Using MetaData only severely restricts the scope of values that can be used- ¿Por qué es eso? Los metadatos se pueden utilizar para señalar definiciones de tipos. Por ejemplo, cuando define un campo en una clase normal, se emiten metadatos que incluyen el nombre del campo y su tipo (Cualquier tipo, no solo primitivas). No entiendo por qué esto no se puede usar para atributos.
Winger Sendon

15

Tengo el mismo problema. Considero usar cadenas . Esto no es seguro para los tipos, pero es legible y creo que podremos escribir números válidos en cadenas :-).

class BlahAttribute : Attribute
{
  private decimal value;

  BlahAttribute(string number)
  {
    value = decimal.Parse(number, CultureInfo.InvariantCulture);
  }
}

[Blah("10.23")]
class Foo {}

No es una belleza, pero después de considerar todas las opciones, es lo suficientemente bueno.


1
Parece que así es como mbUnit hace frente a vkreynin.wordpress.com/2007/05/25/…
Andy Dent

2

Cuando me encontré con esta situación, terminé exponiendo las propiedades del atributo como un Double, pero dentro del atributo las traté como Decimal. Lejos de ser perfecto, pero para los casos simples, podría ser lo que necesita.



0

Puede utilizar el siguiente constructor. Cuando tiene un literal decimal en el código C #, el compilador de C # emite una llamada a este constructor.

Decimal(Int32, Int32, Int32, Boolean, Byte)

Editar: sé que esto no es conveniente.


2
Si esto funcionó en un atributo, supongo que simplemente usar el sufijo "m" también lo haría, pero tampoco lo hace (Usando System.ComponentModel.DefaultValueAttribute como mi prueba)
xr280xr
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.