Pasando matriz estática en atributo

¿Es posible eludir la siguiente restricción?

Cree una matriz de solo lectura estática en una clase:

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

Luego pásalo como parámetro a un atributo:

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

— Digamos que Box es una propiedad de clase A —

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

Sé que esto no se comstackrá y dará lugar a este error:

“Un argumento de atributo debe ser una expresión constante, tipo de expresión o expresión de creación de matriz de un tipo de parámetro de atributo”.

¿Es posible evitar esto de alguna manera para poder utilizar la matriz estática? Estoy preguntando ya que esto será mucho más conveniente en cuanto a mantenimiento, ya que tengo muchas propiedades.

Gracias por adelantado.

Desafortunadamente, esto no es posible. El comstackdor coloca los atributos (incluidos los valores de sus argumentos) en los metadatos del conjunto, por lo que debe ser capaz de evaluarlos en el momento de la comstackción (de ahí la restricción a las expresiones constantes; la excepción para las expresiones de creación de matrices se hizo obviamente porque de lo contrario no podría tener argumentos de matriz en absoluto).

En contraste, el código que realmente inicializa A.Months solo se ejecuta en tiempo de ejecución.

No basicamente

Sin embargo, podría subclasificar el atributo y usarlo, es decir,

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

o:

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

y decorar con [AwesomeFoo] lugar. Si usa la reflexión para buscar FooAttribute , funcionará como se esperaba:

 [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 } } } 

Quizás puedas anidar esto dentro de A , por lo que estás decorando con:

 [A.FooMonths] 

o similar

Respuesta corta: No.

Pero puede referirse a la matriz int por clave:

 public class A { public static readonly Dictionnary NumsArrays = new[]{{1, new[]{1,1,1}}, {2, new[]{2,2,2}}, {3, new[]{3,3,3}}}; public const int Num1 = 1; public const int Num2 = 2; public const int Num3 = 3; } public class FooAttribute : Attribute { public int NumsId { get; set; } FooAttribute() { } } [Foo(NumsID = A.Num3)] public string Box { get; set; } //Evaluation: int id = (FooAttribute) Attribute.GetCustomAttribute(type, typeof (FooAttribute)); int[] result = A.NumsArrays[id];//result is {3,3,3}