114

可変数の引数で初期化できる属性を作成することは可能ですか?

例えば:

[MyCustomAttribute(new int[3,4,5])]  // this doesn't work
public MyClass ...
4

7 に答える 7

191

属性は配列を取ります。ただし、属性を制御する場合は、params代わりに使用することもできます (消費者にとっては、IMO により適しています)。

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(params int[] values) {
       this.Values = values;
    }
}

[MyCustomAttribute(3, 4, 5)]
class MyClass { }

配列作成の構文がたまたまオフになっています。

class MyCustomAttribute : Attribute {
    public int[] Values { get; set; }

    public MyCustomAttribute(int[] values) {
        this.Values = values;
    }
}

[MyCustomAttribute(new int[] { 3, 4, 5 })]
class MyClass { }
于 2008-11-06T20:51:14.050 に答える
40

あなたはそれを行うことができますが、それはCLSに準拠していません:

[assembly: CLSCompliant(true)]

class Foo : Attribute
{
    public Foo(string[] vals) { }
}
[Foo(new string[] {"abc","def"})]
static void Bar() {}

ショー:

Warning 1   Arrays as attribute arguments is not CLS-compliant

通常の反射の使用では、複数の属性を持つことが望ましい場合があります。

[Foo("abc"), Foo("def")]

ただし、これはTypeDescriptor/PropertyDescriptorでは機能しません。ここでは、任意の属性の単一のインスタンスのみがサポートされます(最初または最後のどちらかが勝ち、どちらが勝ったか思い出せません)。

于 2008-11-06T21:50:21.590 に答える
24

次のようにコンストラクターを宣言してみてください。

public class MyCustomAttribute : Attribute
{
    public MyCustomAttribute(params int[] t)
    {
    }
}

次に、次のように使用できます。

[MyCustomAttribute(3, 4, 5)]

于 2008-11-06T20:49:50.387 に答える
13

それは大丈夫です。仕様のセクション 17.2 から:

次のすべてのステートメントが真の場合、式 E はattribute-argument-expressionです。

  • E の型は、属性パラメーター型 (§17.1.3) です。
  • コンパイル時に、E の値は次のいずれかに解決できます。
    • 定数値。
    • System.Type オブジェクト。
    • attribute-argument-expressionsの 1 次元配列。

次に例を示します。

using System;

[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public class SampleAttribute : Attribute
{
    public SampleAttribute(int[] foo)
    {
    }
}

[Sample(new int[]{1, 3, 5})]
class Test
{
}
于 2008-11-06T20:49:08.657 に答える
5

はい。ただし、渡す配列を初期化する必要があります。これは、可変数のコマンド ライン オプションをテストする単体テストの行テストの例です。

[Row( new[] { "-l", "/port:13102", "-lfsw" } )]
public void MyTest( string[] args ) { //... }
于 2008-11-06T20:48:45.757 に答える
2

Marc Gravell の答えに便乗するには、はい、配列パラメーターを使用して属性を定義できますが、配列パラメーターを使用して属性を適用することは CLS に準拠していません。ただし、配列プロパティを使用して属性を定義するだけで、完全に CLS に準拠します。

これに気付いたのは、CLS 準拠のライブラリである Json.NET に、オブジェクトの配列である ItemConverterParameters という名前のプロパティを持つ属性クラス JsonPropertyAttribute があることです。

于 2016-03-18T14:39:50.970 に答える
2

出来るよ。別の例は次のとおりです。

class MyAttribute: Attribute
{
    public MyAttribute(params object[] args)
    {
    }
}

[MyAttribute("hello", 2, 3.14f)]
class Program
{
    static void Main(string[] args)
    {
    }
}
于 2008-11-06T20:50:49.027 に答える