Attribute with params object[] constructor gives inconsistent compiler errors

前端 未结 2 1014
小鲜肉
小鲜肉 2021-01-12 04:59

I am getting the error

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter t

2条回答
  •  一向
    一向 (楼主)
    2021-01-12 05:37

    Assuming your constructor is

    public Foo(params object[] vals) { }
    

    Then i think you are running up against some overlooked and non obvious compiler Dark Magic.

    For example, obviously the below will work

    [Foo(new object[] { "abc", "def" },new object[] { "abc", "def" })]
    [Foo(new string[] { "abc", "def" },new string[] { "abc", "def" })]
    

    This also works for me

    [Foo(new [] { 2 }, new [] { "abc"})]
    [Foo(new [] { 1 }, new [] { "a"})]
    

    However this does not

    [Foo(new [] { "a" })]
    [Foo(new [] { "aaa"})]
    [Foo(new string[] { "aaa" })]
    

    An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

    I think the key take-home peice of information here is

    A method with a params array may be called in either "normal" or "expanded" form. Normal form is as if there was no "params". Expanded form takes the params and bundles them up into an array that is automatically generated. If both forms are applicable then normal form wins over expanded form.

    As an example

    PrintLength(new string[] {"hello"}); // normal form
    PrintLength("hello"); // expanded form, translated into normal form by compiler.
    

    When given a call that is applicable in both forms, the compiler always chooses the normal form over the expanded form.

    However i think this gets even messier again with object[] and even attributes.

    I'm not going to pretend i know exactly what the CLR is doing (and there are many more qualified people that may answer). However for reference, take a look at the CLR SO wizard Eric Lippert's similar answers for a more detailed illumination of what might be going on

    C# params object[] strange behavior

    Why does params behave like this?

    Is there a way to distingish myFunc(1, 2, 3) from myFunc(new int[] { 1, 2, 3 })?

提交回复
热议问题