Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在属性中传递静态数组_C#_Static_Attributes - Fatal编程技术网

C# 在属性中传递静态数组

C# 在属性中传递静态数组,c#,static,attributes,C#,Static,Attributes,是否有可能绕过以下限制: 在类中创建静态只读数组: 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类的一个

是否有可能绕过以下限制:

在类中创建静态只读数组:

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类的一个属性---

我知道这将无法编译,并将导致此错误:

属性参数必须是常量表达式,typeof 属性参数的表达式或数组创建表达式 类型”

有没有可能绕过这个问题,使用静态数组? 我问,因为这将是更方便的维护明智的,因为我有很多财产


提前感谢。

不幸的是,这是不可能的。编译器将属性(包括其参数的值)放入程序集元数据中,因此它必须能够在编译时对其求值(因此对常量表达式的限制;数组创建表达式显然是例外的,因为否则根本就不能有数组参数)

相反,实际初始化A.Months的代码只在运行时执行。

基本上不是

但是,您可以对该属性进行子类化并使用它,即

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

[AwesomeFoo]
来装饰。如果使用反射查找
footAttribute
,它将按预期工作:

[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]
或类似的

简短回答:否

但您可以通过键引用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}
公共A类
{
公共静态只读字典NumsArrays
=新[]{1,新[]{1,1,1},{2,新[]{2,2,2},{3,新[]{3,3,3}};
公共常数int Num1=1;
公共const int Num2=2;
公共常数int Num3=3;
}
公共类footAttribute:属性
{
public int NumsId{get;set;}
footattribute()
{
}
}
[Foo(NumsID=A.Num3)]
公共字符串框{get;set;}
//评价:
intid=(FooAttribute)Attribute.GetCustomAttribute(type,typeof(FooAttribute));
int[]结果=A.NumsArrays[id]//结果是{3,3,3}

从概念上讲,“readonly”应该是“const”吗?可能是,但它们是:readonly关键字与const关键字不同。常量字段只能在声明字段时初始化。只读字段可以在声明或构造函数中初始化。因此,根据使用的构造函数,只读字段可以有不同的值。或者换句话说,属性需要在编译时确定,只读变量在运行时分配?这种理解正确吗?嗯。。。我想知道:如果你只在一个只有反射的环境中反射,会发生什么?@Jon是的,那你就完蛋了。元数据根本不知道内部发生了什么。如果您只能访问元数据,那么您所能说的就是“有一个
awesomefootattribute
,我可以说它本身就是一个
footattribute
”。然而,大多数人并不是只在反射环境中工作。事实上,我确实做了很多(通常是通过IKVM.Reflection)——我感觉到了你的痛苦:)有一分钟,我认为代码是等价的,编译器不厌其烦地看到字段是用一个新数组初始化的。。。这在理论上在这个特定的例子中是可能的,但作为一个特性,这当然是荒谬的,因为它在很多情况下都不起作用。谢谢你澄清这些。@Jon的确,这是99%的运行时间;但这是一个有用的技巧,因为大多数情况下都将使用运行时,而不是反射-only@MarcGravell:谢谢Marc,这是一个有趣的解决方案,尽管我负担不起在构造函数中添加新属性的费用:-(但在机会出现时请记住这一点!Thx,const有帮助
[A.FooMonths]
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}