使用CustomAttributeBuilder时参数不匹配(装箱十进制?)

本文关键字:十进制 CustomAttributeBuilder 参数 不匹配 使用 | 更新日期: 2023-09-27 18:28:48

我有以下代码作为使用反射生成接口的系统的一部分。发射

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类型(bytecharint等)以及string,但在使用decimal时会失败。CustomAttributeBuilder的构造函数失败,出现异常"索引0处传入的参数值与参数类型不匹配"

调试显示所有变量都符合预期:
args有一个类型为object{decimal}的元素
argTypes有一个元素Type=System.Decimal
ctorInfo已经正确地选择了(唯一的)接受对象参数的构造函数。

我已经证明了可以通过直接传递一个十进制参数来实例化属性:

decimal val = 123.456M;
var attr = new DefaultValueAttribute(val);

我试过将小数转换为objectSystem.Decimal,但没有效果。我怀疑这个问题与decimal本身不是POD类型而是一个结构这一事实有关。

我尝试向属性添加构造函数重载(采用decimal类型)。上面的函数正确地获取了新的构造函数,但在同一位置失败,出现异常"无效类型被用作自定义属性构造函数参数、字段或属性"

有人知道我该如何解决这个问题吗?

使用CustomAttributeBuilder时参数不匹配(装箱十进制?)

只需尝试用普通C#代码编写即可:

class TestAttribute : Attribute {
    public TestAttribute(object value) { }
}
[Test(1.2m)]         // NOTE: CS0182
class Example { }

属性构造函数参数不能使用System.Decimal。双人间可以。C#语言规范的17.1.3节暗示了这个问题,但对这个特定的情况没有太具体。十进制是标准值类型的一个子级。例如,在Ecma 335中从未提及。C#编译器使它看起来像一个基本类型,但CLR并没有以同样的方式对待它。