Reflection.emit を使用してインターフェイスを生成するためのシステムの一部として、次のコードがあります。
void IPropertyCreator.AddAttribute<T>(params object[] args)
{
// Convert args to types
var argTypes = new Type[args.Length];
for (int i = 0; i < args.Length; ++i)
{
argTypes[i] = args[i] != null ? args[i].GetType() : null;
}
// Get constructor
var ctorInfo = typeof(T).GetConstructor(argTypes);
// Create custom attribute
var attrBuilder = new CustomAttributeBuilder(ctorInfo, args);
_propertyBuilder.SetCustomAttribute(attrBuilder);
}
T
問題が発生した場合、単一のパラメーターを受け取るコンストラクターを使用して
属性 (typeparam) を作成していますobject
。引数はdecimal
次のコンストラクター (のみ) を持っています。
public DefaultValueAttribute(object value)
このコードは、すべての POD タイプ ( byte
、char
、int
など) で正常にstring
機能しますが、 を使用すると失敗しdecimal
ます。のコンストラクターは、「インデックス 0 で渡された引数値がパラメーターの型と一致しません」というCustomAttributeBuilder
例外で失敗します。
デバッグは、すべての変数が期待どおりであることを示しています:
args
type の 1 つの要素を持っています 1 つの要素をobject{decimal}
argTypes
持っています Type =System.Decimal
ctorInfo
オブジェクト パラメーターを取る (唯一の) コンストラクターを正しく選択しました。
10 進数のパラメーターを直接渡すことで、属性をインスタンス化できることを示しました。
decimal val = 123.456M;
var attr = new DefaultValueAttribute(val);
小数を an に変換し、object
aを無効にしようとしましたSystem.Decimal
。decimal
この問題は、それ自体が POD タイプではなく、構造であるという事実に関連していると思われます。
属性にコンストラクターのオーバーロードを追加しようとしました(decimal
型を取ります)。上記の関数は新しいコンストラクターを正しく取得しましたが、同じ場所で「カスタム属性コンストラクターの引数、フィールド、またはプロパティとして無効な型が使用されました」という例外で失敗しました。
これを回避する方法を知っている人はいますか?