在属性中传递静态数组
本文关键字:静态 数组 属性 | 更新日期: 2023-09-27 18:15:11
是否有可能绕过以下限制:
在类中创建静态只读数组:
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属性参数的表达式或数组创建表达式类型"。
是否有可能绕过这个以某种方式能够使用静态数组?我之所以这样问,是因为这样在维护方面会方便得多,因为我有很多属性。
不幸的是这是不可能的。属性(包括其参数的值)由编译器放置到程序集元数据中,因此它必须能够在编译时对它们进行计算(因此对常量表达式的限制;对于数组创建表达式的异常很明显,因为否则你根本就不能有数组参数)。
相反,实际初始化A.Months
的代码只在运行时执行。
基本上没有。
但是,您可以将子类化为属性并使用它,即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]
或类似
简短回答:No.
但是你可以通过键来引用int数组:
public class A
{
public static readonly Dictionary<int, int[]> 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}