可変数の引数で初期化できる属性を作成することは可能ですか?
例えば:
[MyCustomAttribute(new int[3,4,5])] // this doesn't work
public MyClass ...
属性には配列が必要です。ただし、属性を制御する場合は、代わりに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 { }
できますが、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
では機能しません。どの属性のインスタンスも1つしかサポートされていません(最初の勝ちか最後の勝ちか、どちらを思い出すことはできません)。
次のようにコンストラクタを宣言してみてください。
_public class MyCustomAttribute : Attribute
{
public MyCustomAttribute(params int[] t)
{
}
}
_
その後、次のように使用できます。
[MyCustomAttribute(3, 4, 5)]
大丈夫なはずです。仕様のセクション17.2から:
式Eは、次のステートメントがすべて当てはまる場合、attribute-argument-expressionです。
以下に例を示します。
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
{
}
はい。ただし、渡す配列を初期化する必要があります。これは、可変数のコマンドラインオプションをテストする単体テストの行テストの例です。
[Row( new[] { "-l", "/port:13102", "-lfsw" } )]
public void MyTest( string[] args ) { //... }
出来るよ。別の例は次のとおりです。
class MyAttribute: Attribute
{
public MyAttribute(params object[] args)
{
}
}
[MyAttribute("hello", 2, 3.14f)]
class Program
{
static void Main(string[] args)
{
}
}
Marc Gravellの答えに便乗するために、はい、配列パラメーターで属性を定義できますが、配列パラメーターで属性を適用することはCLSに準拠していません。ただし、配列プロパティで属性を定義するだけで、CLSに完全に準拠します。
これに気づいたのは、CLS準拠のライブラリであるJson.NETには、オブジェクトの配列であるItemConverterParametersというプロパティを持つ属性クラスJsonPropertyAttributeがあることです。