10

次の制限を回避することは可能ですか?

クラスに読み取り専用の静的配列を作成します。

public class A
{
    public static readonly int[] Months = new int[] { 1, 2, 3};
}

次に、それをパラメーターとして属性に渡します。

public class FooAttribute : Attribute
{
    public int[] Nums { get; set; }

    FooAttribute()
    {
    }
}

--- Box がクラス A のプロパティであるとしましょう ---

[Foo(Nums = A.Months)]
public string Box { get; set; }

これがコンパイルされず、次のエラーが発生することはわかっています。

「属性引数は、定数式、typeof 式、または属性パラメーター型の配列作成式でなければなりません」。

静的配列を使用できるようにするために、これを回避することは可能ですか? 私は多くのプロパティを持っているので、これはメンテナンスに関してはるかに便利になるので、私は尋ねています。

前もって感謝します。

4

3 に答える 3

12

いいえ、基本的に。

ただし、属性をサブクラス化して使用することもできます。

class AwesomeFooAttribute : FooAttribute {
    public AwesomeFooAttribute() : FooAttribute(A.Months) {}
}

また:

class AwesomeFooAttribute : FooAttribute {
    public AwesomeFooAttribute() {
        Nums = A.Months;
    }
}

代わりに飾り[AwesomeFoo]ます。リフレクションを使用して を探すとFooAttribute、期待どおりに機能します。

[AwesomeFoo]
static class Program
{
    static void Main()
    {
        var foo = (FooAttribute)Attribute.GetCustomAttribute(
            typeof(Program), typeof(FooAttribute));
        if (foo != null)
        {
            int[] nums = foo.Nums; // 1,2,3
        }
    }
}

これを の中にネストすることもできるAので、次のように装飾します。

[A.FooMonths]

または類似

于 2013-05-23T09:48:33.440 に答える
11

残念ながら、これは不可能です。属性 (引数の値を含む) はコンパイラによってアセンブリ メタデータに配置されるため、コンパイル時にそれらを評価できる必要があります (したがって、定数式に対する制限です。配列作成式の例外は明らかに作成されました。配列引数をまったく持つことができませんでした)。

対照的に、実際に初期化するコードA.Monthsは実行時にのみ実行されます。

于 2013-05-23T09:47:22.450 に答える