C#の属性パラメータとして10進値を使用しますか?


81

フィールド属性のパラメータとして10進値を使用しようとしましたが、コンパイラエラーが発生します。

.NETでは使用できなかったというこのブログ投稿リンクを見つけました。なぜこれを選択するのか、または10進パラメーターを使用するにはどうすればよいか誰か知っていますか?


回答:


123

これはCLRの制限です。属性パラメーターとして使用できるのは、プリミティブ定数またはプリミティブの配列のみです。その理由は、属性を完全にメタデータでエンコードする必要があるためです。これは、ILでコード化されているメソッド本体とは異なります。MetaDataを使用すると、使用できる値の範囲が厳しく制限されるだけです。CLRの現在のバージョンでは、メタデータ値はプリミティブ、null、プリミティブの型と配列に制限されています(マイナーなものを見逃している可能性があります)。

基本型はプリミティブ型ではないため、メタデータで表すことができないため、属性パラメーターになることができません。


5
これはまだFramework4.0の問題ですか?および4.5、4.6.x?
ミッドスペース2016年

@midspaceは、実際には問題ではなく、設計によって課せられた単なる制限です。残念ながら、消えることはないかもしれません。
ブルーノブラント

1
「属性パラメータとして使用できるのは、プリミティブ定数またはプリミティブの配列のみです。」正確には当てはまらないようです。たとえば、System.Typeも許可されています:msdn.microsoft.com/en-us/library/aa664615
v

Using MetaData only severely restricts the scope of values that can be used-それはなぜですか?メタデータは、タイプ定義を指すために使用できます。たとえば、通常のクラスでフィールドを定義すると、フィールドの名前とそのタイプ(jutsプリミティブではなく、任意のタイプ)を含むメタデータが発行されます。これが属性に使用できない理由がわかりません。
wingerse 2017年

16

私は同じ問題を抱えています。文字列の使用を検討しています。これはタイプセーフではありませんが、読み取り可能であり、有効な数値を文字列に書き込むことができると思います:-)。

class BlahAttribute : Attribute
{
  private decimal value;

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

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

それは美しさではありませんが、すべてのオプションを検討した後、それで十分です。


1
mbUnitがvkreynin.wordpress.com/2007/05/25/…に対処する方法のように見えます
Andy Dent

2

この状況に遭遇したとき、属性のプロパティをDoubleとして公開することになりましたが、属性内ではそれらをDecimalのように扱いました。完璧にはほど遠いですが、単純なケースでは、それが必要な場合があります。



0

次のコンストラクターを使用できます。C#コードに10進リテラルがある場合、C#コンパイラはこのコンストラクターへの呼び出しを発行します。

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

編集:私はこれが便利ではないことを知っています。


2
これが属性で機能する場合は、単に「m」サフィックスを使用することもできると思いますが、どちらも機能しません(System.ComponentModel.DefaultValueAttributeをテストとして使用)
xr280xr 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.