2010-07-07 13 views
93

È davvero incredibile ma reale. Questo codice non funziona:Perché "decimale" non è un tipo di parametro dell'attributo valido?

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

Anche se questo funziona:

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

Chi sa dirmi il motivo per cui è doppia OK mentre decimale non è.

+0

possibile duplicato di [utilizzare valori decimali come parametri di attributo in C#?] (Http: // stackoverflow.it/questions/507528/use-decimal-values-as-attribute-params-in-c) – nawfal

risposta

100

Si tratta di una limitazione CLR. Solo le costanti o le matrici primitive primitive possono essere utilizzate come parametri . Il motivo per cui un attributo deve essere codificato interamente nei metadati . Questo è diverso da un corpo del metodo che è codificato in IL. L'utilizzo di MetaData limita severamente lo l'ambito dei valori che è possibile utilizzare. Nella versione corrente di CLR, i valori dei metadati sono limitati a primitive , null, tipi e matrici di primitive (potrebbe essersi perso un minore ).

Scattata da this risposta da JaredPar.

decimali mentre un tipo di base non sono un tipo primitivo e quindi non può essere rappresentato in metadati che impedisce da essere un parametro di attributo.

+23

Perché i decimali non sono considerati tipi primitivi nel CLR? – koumides

+7

@koumides credo che la risposta il tipo è troppo grande per essere espresso in un singolo registro CPU poiché è 128 bit –

+0

OK, quindi perché le stringhe sono consentite come proprietà degli attributi? Suppongo che rientri nella categoria 'array of primitives' ma è allocata su heap (tipo di riferimento). .. – Steztric

38

Dalle specs:

I tipi di parametri posizionali e nominato per una classe di attributo sono limitati ai tipi di parametri di attributo, che sono:

  • Uno dei seguenti tipi: bool , byte, char, double, float, int, long, sbyte, short, string, uint, ulong, ushort.
  • Il tipo object.
  • Il tipo System.Type.
  • Un tipo di enum, a condizione che abbia accessibilità pubblica e che i tipi in cui è nidificato (se presenti) dispongano anche di accessibilità pubblica (specifica dell'attributo).
  • Matrici unidimensionali dei tipi precedenti.
+9

Corretto, ma nota che stai citando una vecchia versione della specifica. Nelle versioni C# 3.0, 4.0 e 5.0, si afferma che può anche avere tipo 'sbyte',' ushort', 'uint',' ulong'. E sembra funzionare bene. Ma ancora 'decimal' non è consentito :-( –

+1

@JeppeStigNielsen Ho aggiornato il collegamento delle specifiche e cito –

+0

Anche le primitive non utilizzabili sono supportate – KTCO

0

La risposta a questo problema è utilizzare stringhe, che sono consentite come attributi nonostante non siano di tipo atomico. Non usare doppi perché l'arrotondamento renderà i risultati meno precisi.

Problemi correlati