c# - property - ¿Por qué "decimal" no es un tipo de parámetro de atributo válido?
custom property c# (3)
Esta es una restricción CLR. Solo las constantes primitivas o matrices de primitivas se pueden usar como parámetros de atributos. La razón es que un atributo debe codificarse completamente en metadatos. Esto es diferente de un cuerpo de método que está codificado en IL. El uso de MetaData solo restringe severamente el alcance de los valores que se pueden usar. En la versión actual del CLR, los valores de metadatos están limitados a primitivos, nulos, tipos y matrices de primitivas (puede haber pasado por alto uno menor).
Tomado de this respuesta por JaredPar .
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 impide que sea un parámetro de atributo.
Es realmente increíble pero real. Este código no funcionará:
[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
public decimal Max { get; set; }
public decimal Min { get; set; }
}
public class Item
{
[Range(Min=0m,Max=1000m)] //compile error:''Min'' is not a valid named attribute argument because it is not a valid attribute parameter type
public decimal Total { get; set; }
}
Mientras esto funciona:
[AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
public class Range : Attribute
{
public double Max { get; set; }
public double Min { get; set; }
}
public class Item
{
[Range(Min=0d,Max=1000d)]
public decimal Total { get; set; }
}
¿Quién puede decirme por qué el doble está bien mientras que el decimal no?
De las specs :
Los tipos de parámetros posicionales y nominales para una clase de atributo están limitados a los tipos de parámetros de atributo, que son:
- Uno de los siguientes tipos:
bool
,byte
,char
,double
,float
,int
,long
,sbyte
,short
,string
,uint
,ulong
,ushort
.- El tipo de
object
- El tipo
System.Type
.- Un tipo de enumeración, siempre que tenga acceso público y los tipos en los que está anidado (si lo hay) también tienen acceso público (especificación de atributo).
- Arrays unidimensionales de los tipos anteriores.
La respuesta a este problema es usar cadenas, que están permitidas como atributos a pesar de no ser un tipo atómico. No use dobles ya que el redondeo hará que los resultados sean menos precisos.
public String MinimumValue
{
get
{
return minimumValueDecimal.ToString();
}
set
{
minimumValueDecimal = Decimal.Parse(value);
}
}
private decimal minimumValueDecimal;