Dezimalwerte als Attributparameter in c # verwenden?


81

Ich habe versucht, Dezimalwerte als Parameter für ein Feldattribut zu verwenden, erhalte jedoch einen Compilerfehler.

Ich habe diesen Blogpost- Link gefunden, der besagt, dass es in .NET damals nicht möglich war, ihn zu verwenden. Weiß jemand, warum er dies wählt oder wie ich Dezimalparameter verwenden kann?


Antworten:


121

Dies ist eine CLR-Einschränkung. Nur primitive Konstanten oder Arrays von Primitiven können als Attributparameter verwendet werden. Der Grund dafür ist, dass ein Attribut vollständig in Metadaten codiert werden muss. Dies unterscheidet sich von einem Methodenkörper, der in IL codiert ist. Die Verwendung von MetaData schränkt den Umfang der Werte, die verwendet werden können, nur stark ein. In der aktuellen Version der CLR sind Metadatenwerte auf Grundelemente, Null, Typen und Arrays von Grundelementen beschränkt (möglicherweise wurde ein untergeordnetes Element übersehen).

Dezimalstellen, während ein Basistyp kein primitiver Typ ist und daher nicht in Metadaten dargestellt werden kann, wodurch verhindert wird, dass er ein Attributparameter ist.


5
Ist dies immer noch ein Problem mit Framework 4.0? und 4.5, 4.6.x?
Midspace

@midspace, nicht wirklich ein Problem, nur eine Einschränkung, die durch das Design auferlegt wird. Es ist unglücklich, aber gute Chancen, dass es nie verschwinden wird.
Bruno Brant

1
"Nur primitive Konstanten oder Arrays von Primitiven können als Attributparameter verwendet werden." Es scheint nicht genau zu stimmen, zum Beispiel ist System.Type auch erlaubt: 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- Warum ist das so? Metadaten können verwendet werden, um auf Typdefinitionen zu verweisen. Wenn Sie beispielsweise ein Feld in einer regulären Klasse definieren, werden Metadaten ausgegeben, die den Namen des Felds und seinen Typ enthalten (Beliebiger Typ, keine übergeordneten Grundelemente). Ich verstehe nicht, warum dies nicht für Attribute verwendet werden kann.
Flügelspieler Sendon

15

Ich habe das gleiche Problem. Ich denke darüber nach, Strings zu verwenden . Dies ist nicht typsicher, aber lesbar und ich denke, wir können gültige Zahlen in Strings schreiben :-).

class BlahAttribute : Attribute
{
  private decimal value;

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

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

Es ist keine Schönheit, aber nach Abwägung aller Optionen ist es gut genug.


1
Sieht so aus, als würde mbUnit
Andy Dent

2

Wenn ich in diese Situation geraten bin, habe ich die Eigenschaften des Attributs als Double angezeigt, aber innerhalb des Attributs wurden sie wie Dezimal behandelt. Weit davon entfernt, perfekt zu sein, aber für die einfachen Fälle könnte es genau das sein, was Sie brauchen.



0

Sie können den folgenden Konstruktor verwenden. Wenn Sie ein Dezimalliteral in C # -Code haben, gibt der C # -Compiler einen Aufruf an diesen Konstruktor aus.

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

Bearbeiten: Ich weiß, das ist nicht bequem.


2
Wenn dies in einem Attribut funktioniert hätte, würde ich auch einfach das Suffix "m" verwenden, aber auch nicht (mit System.ComponentModel.DefaultValueAttribute als Test)
xr280xr
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.