web-dev-qa-db-fra.com

Pourquoi "décimal" n'est pas un type de paramètre d'attribut valide?

C'est vraiment incroyable mais réel. Ce code ne fonctionnera pas:

[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; }  
}

Pendant que cela fonctionne:

[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 peut me dire pourquoi le double est OK alors que le nombre décimal ne l'est pas.

125
Cheng Chen

Il s'agit d'une restriction CLR. Seules les constantes primitives ou les tableaux de primitives peuvent être utilisés comme paramètres d'attribut. La raison en est qu'un attribut doit être entièrement codé en métadonnées. Ceci est différent d'un corps de méthode qui est codé en IL. L'utilisation de MetaData ne limite que considérablement la portée des valeurs qui peuvent être utilisées. Dans la version actuelle du CLR, les valeurs des métadonnées sont limitées aux primitives, null, types et tableaux de primitives (peut-être en ont manqué un mineur).

Tiré de this réponse par JaredPar .

Les décimales alors qu'un type de base ne sont pas un type primitif et ne peuvent donc pas être représentées dans des métadonnées, ce qui l'empêche d'être un paramètre d'attribut.

125
djdd87

À partir de spécifications :

Les types de paramètres positionnels et nommés pour une classe d'attributs sont limités aux types de paramètres d'attribut, qui sont:

  • L'un des types suivants: bool, byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort.
  • Le type object.
  • Le type System.Type.
  • Un type enum, à condition qu'il ait une accessibilité publique et que les types dans lesquels il est imbriqué (le cas échéant) aient également une accessibilité publique (spécification d'attribut).
  • Tableaux unidimensionnels des types ci-dessus.
50
Kobi

La réponse à ce problème consiste à utiliser des chaînes, qui sont autorisées en tant qu'attributs bien qu'elles ne soient pas de type atomique. N'utilisez pas de double car l'arrondi rendra les résultats moins précis.

public String MinimumValue
{
    get
    {
        return minimumValueDecimal.ToString();
    }

    set
    {
        minimumValueDecimal = Decimal.Parse(value);
    }
}

private decimal minimumValueDecimal;
1
Daniel Barbalace