6

コンストラクターで(params)配列を受け入れる属性を作成しました。

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

Optionここに列挙型(値がたくさんある)があるので、サンプルの呼び出しサイトは次のようになります

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

これまでのところすべてが桃色で、セットアップは機能しますが、各呼び出しサイトで「属性引数としての配列はCLSに準拠していません」という警告が表示されます。ここで、C#以外の場所からこのアセンブリを使用する必要はなく、エラーとしての警告も実行する必要がないことを認める必要がありますが、何百もの警告が煩わしくなります。

明らかな解決策はCLS準拠をオフにすることですが、現時点ではそれを行うことはできません。

同じことを実行するが、警告を取り除く属性を作成するための他のアプローチはありますか?

4

2 に答える 2

12

2 つのオプション:

1: 代わりにいくつかのオーバーロードを追加できます:

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:Optionsが列挙型の場合、列挙型を列挙型としてマークし[Flags]、呼び出し元にそれらを結合させます。

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

と:

[Flags]
public enum Option {
     None = 0,
     One = 1,
     Two = 2,
     Three = 4,
     Four = 8,
     ...
}
于 2011-10-31T08:08:39.643 に答える
5

「属性引数としての配列は CLS に準拠していません」

まさにそれが言うこと。

唯一の回避策は、明示的なパラメーターを作成することです。たとえば、次のようになります。

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)
    {
        ....
    }
}

注:属性クラスが internal であることを考えると、CLS が準拠されているのは面白いことです。私の知る限り、CLSは可能な外部メンバー(パブリック/保護)で検証されることのみを目的としています。

于 2011-10-31T08:09:23.343 に答える