枚举成员应该使用哪种AttributeTarget?

62

我想要像这样在枚举成员中使用我的IsGPUBasedAttribute

public enum EffectType
{
    [IsGPUBased(true)]
    PixelShader,

    [IsGPUBased(false)]
    Blur
}

但编译器不允许我使用:

[AttributeUsage (AttributeTargets.Enum, AllowMultiple = false)]

如何正确设置AttributeTarget值,以限制其作用于枚举成员?


现在可以使用它了(从Net5开始)https://learn.microsoft.com/en-us/dotnet/api/system.attributetargets?view=net-5.0 - Tena
4个回答

75
据我所知,没有专门针对枚举常量的选项。你可能能够得到最接近的是“Field”,它将使用限制在类或结构体的字段成员上(枚举常量在属性方面被视为这样)。 编辑:从评论中解释“为什么”,枚举常量就是这样,因此它们的值和用法直接嵌入到IL中。因此,枚举声明实际上与创建具有静态常量成员的静态类定义并没有太大区别:
public static class MyEnum
{
    public const int Value1 = 0;
    public const int Value2 = 1;
    public const int Value3 = 2;
    public const int Value4 = 3;        
}

唯一的区别是它派生自 System.Enum,它是一个值类型而不是引用类(你不能创建静态结构体,也不能创建不可构造的结构体)。


谢谢,那个可行。你知道为什么微软没有为枚举常量提供一个吗? - Joan Venge
因为在编译级别上,枚举常量和普通成员字段之间没有太大的区别;您必须检查包含类型并确定它派生自 Enum。此外,真的没有太多需要仅适用于枚举常量的属性。我曾经应用于枚举常量的唯一一个是来自 System.ComponentModel 的 DescriptionAttribute,据我所知,它可以应用于任何东西。 - KeithS
谢谢,我也只是在枚举常量中使用了DescriptionAttribute,这是我在实际代码中使用的类似属性。 - Joan Venge
你说它们并没有太大区别,但enum成为一等公民最大的区别是它们为你提供了一种强类型方式来处理它。在你的情况下,我可以这样做:if(MyEnum.Value1 == 235)或者int i = MyEnum.Value1;i = SomeOtherEnum.Value1等等,但是对于枚举(不进行某些显式转换)则不可能。 - nawfal
我知道这篇文章很旧了,但我的当前情况是基于一个输入值随机选择枚举值,使某些选项更有可能发生并排除不能进行随机的选项。 public enum Test { [DisallowRandom]None,[Entry(4)]Test1,[Entry(2)]Test2,[Entry(1)]Test3} - user3915050

36

AttributeTargets.Field 允许您为枚举值使用属性。

[AttributeUsage(AttributeTargets.Field)]

1
不是完美的,但仍然比“全部”更具约束力,谢谢。 - AFract

4

没有一种方法可以指定属性仅可用于枚举成员。老实说,如果您将要使用多个此类属性,则最好创建自己的Effect(或EffectType)类,并将其实现为普通属性。

例如:

public class EffectType
{
    public bool IsGpuBased { get; private set; }

    private EffectType(bool isGpuBased)
    {
        IsGpuBased = isGpuBased;
    }

    public static readonly EffectType PixelShader = new EffectType(true);
    public static readonly EffectType Blur = new EffectType(false);
}

采用这种方法,你的代码将更易于阅读,并且与元数据提取相比性能更好。

1
谢谢,实际代码并不是这样的,我只是想提供一个简化的假设例子来说明问题。 - Joan Venge
@Joan:我认为我仍然会坚持我的建议。 - Adam Robinson
1
没关系,我只是想说我发布的代码是虚构的,因为我只想知道将属性限制为枚举常量的限制。 - Joan Venge
@Joan:关于那个问题,我赞同@KeithS的评论,因为很可能是因为没有足够的需求而没有这个功能。我仍然认为,与使用属性相比,自定义类型是更好的选择 ;) - Adam Robinson

1
[AttributeUsage(AttributeTargets.Field)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接