Dlaczego "decimal" nie jest prawidłowym typem parametru atrybutu?

To naprawdę niewiarygodne, ale prawdziwe. Ten kod nie zadziała:

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

Podczas gdy to działa:

[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; }  
}
Kto mi powie, dlaczego podwójne jest OK, a dziesiętne nie.
Author: Danny Chen, 2010-07-07

3 answers

Jest to ograniczenie CLR. Tylko prymitywne stałe lub tablice prymitywy mogą być użyte jako atrybut parametry. Powodem jest to, że atrybut musi być zakodowany w całości w metadane. To coś innego niż ciało metody kodowane w IL. Korzystanie z metadanych poważnie ogranicza zakres wartości, które mogą być użyte. W obecnej wersji CLR, wartości metadanych są ograniczone do primitives, null, types and arrays of prymitywy (mogły przeoczyć drobne jeden).

Wzięte z tej odpowiedzi przez JaredPar .

Dziesiętne, podczas gdy Typ podstawowy nie jest prymitywny typ i stąd nie może być reprezentowane w metadanych, co uniemożliwia to od bycia parametrem atrybutu.

 111
Author: GenericTypeTea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:43

From the specs :

Typy parametrów pozycyjnych i nazwanych dla klasy atrybutów są ograniczone do typów parametrów atrybutów, które są:

  • jeden z następujących typów: bool, byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort.
  • Typ object.
  • Typ System.Type.
  • Typ enum, pod warunkiem, że ma dostęp publiczny i typy, w których jest zagnieżdżony (jeśli istnieją) mają również dostęp publiczny (Specyfikacja atrybutów).
  • tablice jednowymiarowe powyższych typów.
 46
Author: Kobi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-25 14:54:13

Odpowiedzią na ten problem jest użycie łańcuchów, które są dozwolone jako atrybuty, mimo że nie są typem atomowym. Nie używaj podwajania, ponieważ zaokrąglenie sprawi, że wyniki będą mniej dokładne.

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

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

private decimal minimumValueDecimal;
 0
Author: Daniel Barbalace,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-27 00:50:05