1

I have the following attribute definition:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
class TestAttribute : Attribute
{
      public TestAttribute(List<string> values)
      {
      }
}

The following use of the attribute produces an error:

[Test(new List<string>() { "123", "456" }]
class A
{
}

The error is:

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

Any help please? I'm using Visual Studio 2012 .NET 4.5.

I don't want to use params string[] instead of List<string>.

11
  • I'm sorry i just edited the question guys, can you have a look at it now. Commented Oct 23, 2013 at 19:05
  • yep - now it makes sense! Commented Oct 23, 2013 at 19:06
  • I don't want to use params string[] instead of List<string>.: unfortunately that's not going to matter. The CLR isn't going to allow anything else. Commented Oct 23, 2013 at 19:06
  • 2
    Why don't you wanna use params? Whats wrong with that? seems perfect Commented Oct 23, 2013 at 19:07
  • 1
    You can use it inside the constructor, just not as an argument. Commented Oct 23, 2013 at 19:10

2 Answers 2

6

As the error message told you, you supply that as an argument to an attribute constructor. Generally anything you have to create with new is not valid as that is not constant but allocated at run time.

As the error message suggests, you could just use an array instead. In your case, it’s very simple to do with a params array:

public TestAttribute(params string[] values)
{ }

Then you can use it like this:

[Test("123", "456")]
class A
{ }

Note though, that you have defined TestAttribute to be only valid for methods, not for class declarations. So this will still fail.


I don't want to use params string[] instead of List<string>.

Well, you don’t have much of a choice, you could use a plain array, so you would have to write new string[] {"123", "456"} instead—that doesn’t give you any benefit though.

If you really want a list, although there really shouldn’t be a need for it, you can create it in the constructor:

public TestAttribute(params string[] values)
{
    List<string> valuesList = new List<string>(values);
}

I want to pass objects of specific types not something static.

You cannot ever pass anything dynamic to attributes. They are evaluated quite early when the declaration is processed, so at that time it’s unlikely that the rest of your code was executed.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks lot you does gave it all!
5

Just like the message sais, it's simply not supported in c#. (The reason is that attributes are metadata and it should be possible to reflect/read metadata without executing code - such as initializing a list).

But you can use the params keyword:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
class TestAttribute : Attribute
{
    public TestAttribute(params string[] values)
    {
    }
}

[Test("123", "456")]
class A
{
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.