używać wartości dziesiętnych jako parametrów atrybutów w języku C #?


81

Próbowałem użyć wartości dziesiętnych jako parametrów atrybutu pola, ale pojawia się błąd kompilatora.

Znalazłem ten link do posta na blogu, który mówi, że nie można było wtedy używać w .NET, czy ktoś wie, dlaczego wybrał to lub jak mogę używać paramatów dziesiętnych?


Odpowiedzi:


123

To jest ograniczenie CLR. Jako parametry atrybutów można używać tylko stałych pierwotnych lub tablic prymitywów. Powodem jest to, że atrybut musi być zakodowany w całości w metadanych. Różni się to od treści metody, która jest zakodowana w języku IL. Korzystanie z MetaData tylko poważnie ogranicza zakres wartości, których można użyć. W aktualnej wersji środowiska CLR wartości metadanych są ograniczone do prymitywów, wartości null, typów i tablic prymitywów (mogły zostać pominięte drugorzędne).

Liczby dziesiętne, podczas gdy typ podstawowy nie jest typem pierwotnym i dlatego nie mogą być reprezentowane w metadanych, co uniemożliwia mu bycie parametrem atrybutu.


5
Czy to nadal problem z Framework 4.0? i 4.5, 4.6.x?
midspace

@midspace, nie jest to naprawdę problem, tylko ograniczenie, narzucone przez projekt. To niefortunne, ale są duże szanse, że nigdy nie zniknie.
Bruno Brant

1
„Tylko stałe prymitywne lub tablice prymitywów mogą być używane jako parametry atrybutów”. Wydaje się, że nie jest to do końca prawdą, na przykład dozwolony jest również System.Type: 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- Dlaczego tak jest? Metadane mogą służyć do wskazywania definicji typów. Na przykład, kiedy definiujesz pole w zwykłej klasie, emitowane są metadane zawierające nazwę pola i jego typ (Dowolny typ, a nie juts prymitywy). Nie rozumiem, dlaczego nie można tego używać do atrybutów.
Skrzydłowy Sendon

16

Mam ten sam problem. Rozważam użycie ciągów . To nie jest bezpieczne dla typów, ale jest czytelne i myślę, że będziemy w stanie zapisać prawidłowe liczby w łańcuchach :-).

class BlahAttribute : Attribute
{
  private decimal value;

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

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

To nie jest piękno, ale po rozważeniu wszystkich opcji jest wystarczająco dobre.


1
Wygląda na to, że tak radzi sobie mbUnit vkreynin.wordpress.com/2007/05/25/…
Andy Dent

2

Kiedy natknąłem się na tę sytuację, w końcu ujawniłem właściwości atrybutu jako Double, ale wewnątrz atrybutu traktowałem je jak Decimal. Daleko od ideału, ale w prostych przypadkach może być to, czego potrzebujesz.



0

Możesz użyć następującego konstruktora. Gdy masz literał dziesiętny w kodzie C #, kompilator C # emituje wywołanie do tego konstruktora.

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

Edycja: wiem, że to nie jest wygodne.


2
Gdyby to zadziałało w atrybucie, zgaduję, że po prostu byłoby to za pomocą przyrostka „m”, ale też nie (przy użyciu System.ComponentModel.DefaultValueAttribute jako mojego testu)
użyłoby
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.