CLS compliant attributes and array parameters
Asked Answered
B

2

6

I have created an attribute that accepts a (params) array in its constructor.

internal class MyTestAttribute : Attribute
{
    public MyTestAttribute (params Options[] options)
    {
        ....
    }
}

Option here is an enum (with lots of values), so a sample call site will be

[MyTest(Option.One, Option.Three)]
internal void SomeMethod(int param1, long param2)
{
  ....
}

Everything is peachy so far, and the setup works, but I'm receiving an "Arrays as attribute arguments is not CLS-compliant" warning on each call-site. Now, I have to admit that I do not need to use this assembly from anywhere other that C#, nor do I do warnings-as-errors, but the hundreds of warnings are getting annoying.

The obvious solution is to turn off CLS-compliance, but at the moment I can't do that.

Is there some other approach to the creation of the attribute that will still do the same thing, but get rid of the warnings?

Bendy answered 31/10, 2011 at 8:3 Comment(0)
C
12

Two options:

1: you could add some overloads instead:

private MyTestAttribute(Option[] options) {...}
public MyTestAttribute(Option option0)
          : this(new[] {option0}) {}
public MyTestAttribute(Option option0, Option option1)
          : this(new[] {option0, option1}) {}
public MyTestAttribute(Option option0, Option option1, Option option2)
          : this(new[] {option0, option1, option2}) {}
// add a few more, without going crazy

2: if Options is an enum, mark the enum as a [Flags] enum, and have the caller combine them:

[MyTest(Option.One | Option.Two)]

with:

[Flags]
public enum Option {
     None = 0,
     One = 1,
     Two = 2,
     Three = 4,
     Four = 8,
     ...
}
Clarkclarke answered 31/10, 2011 at 8:8 Comment(3)
Arg, beat me! But why is CLS complaining on an internal attribute class?Cocaine
Yes, Option is an enum, and the call site will use at most three or four options, so this is a great solution. Tnx, I had a feeling I was overlooking something obvious :)Bendy
@leppie, it's not complaining on the definition of the attribute (it does if it's public), it's complaining on the public call sites.Bendy
C
5

"Arrays as attribute arguments is not CLS-compliant"

Exactly what it says.

The only workaround is to create explicit parameters, eg:

internal class MyTestAttribute : Attribute
{
    public MyTestAttribute(Option o1) : this(new Option[] { o1 }) {}
    public MyTestAttribute(Option o1, Option o2) : 
      this(new Option[] { o1, o2 }) {}

    MyTestAttribute (Options[] options)
    {
        ....
    }
}

Note: It is funny though that CLS is being complianed about given the attribute class is internal. AFAIK, CLS is only meant to be validated on possible external members (public/protected).

Cocaine answered 31/10, 2011 at 8:9 Comment(1)
It's not complaining on the definition of the attribute (it does if it's public), it's complaining on the public call sites.Bendy

© 2022 - 2024 — McMap. All rights reserved.