フィールド属性のパラメータとして10進値を使用しようとしましたが、コンパイラエラーが発生します。
.NETでは使用できなかったというこのブログ投稿リンクを見つけました。なぜこれを選択するのか、または10進パラメーターを使用するにはどうすればよいか誰か知っていますか?
回答:
これはCLRの制限です。属性パラメーターとして使用できるのは、プリミティブ定数またはプリミティブの配列のみです。その理由は、属性を完全にメタデータでエンコードする必要があるためです。これは、ILでコード化されているメソッド本体とは異なります。MetaDataを使用すると、使用できる値の範囲が厳しく制限されるだけです。CLRの現在のバージョンでは、メタデータ値はプリミティブ、null、プリミティブの型と配列に制限されています(マイナーなものを見逃している可能性があります)。
基本型はプリミティブ型ではないため、メタデータで表すことができないため、属性パラメーターになることができません。
Using MetaData only severely restricts the scope of values that can be used
-それはなぜですか?メタデータは、タイプ定義を指すために使用できます。たとえば、通常のクラスでフィールドを定義すると、フィールドの名前とそのタイプ(jutsプリミティブではなく、任意のタイプ)を含むメタデータが発行されます。これが属性に使用できない理由がわかりません。
私は同じ問題を抱えています。文字列の使用を検討しています。これはタイプセーフではありませんが、読み取り可能であり、有効な数値を文字列に書き込むことができると思います:-)。
class BlahAttribute : Attribute
{
private decimal value;
BlahAttribute(string number)
{
value = decimal.Parse(number, CultureInfo.InvariantCulture);
}
}
[Blah("10.23")]
class Foo {}
それは美しさではありませんが、すべてのオプションを検討した後、それで十分です。
属性を持つリアルタイムのトリックには、TypeConverterクラスを使用しています。
次のコンストラクターを使用できます。C#コードに10進リテラルがある場合、C#コンパイラはこのコンストラクターへの呼び出しを発行します。
Decimal(Int32, Int32, Int32, Boolean, Byte)
編集:私はこれが便利ではないことを知っています。