Reputation: 330992
I want to use my IsGPUBasedAttribute
for enum members like this:
public enum EffectType
{
[IsGPUBased(true)]
PixelShader,
[IsGPUBased(false)]
Blur
}
but the compiler doesn't let me to use:
[AttributeUsage (AttributeTargets.Enum, AllowMultiple = false)]
What is the right AttributeTarget
value to limit the usage to enum members?
Upvotes: 67
Views: 18944
Reputation: 655
So I understand that this is an old question, and 'correct' but somehow unstatisfying answer of AttributeTargets.Field was also given by a number of people, I'd like to share how I got to that answer; I set up an enum and created the desired attribute class. I started this process with AttributeTargets.All , obviously this removed any error for random previous attempts created.
However, I declared it like this..
[AttributeUsage((AttributeTargets)32767, AllowMultiple = false, Inherited = true)]
Then it was easy, just start subtracting the values of flags until I was left with only one bit left... which of course turned out to be AttributeTargets.Field, or rather:
[AttributeUsage((AttributeTargets)256, AllowMultiple = false, Inherited = true)]
While this is the exact same value as Field, I now leave it this way in my code when it's intended to be applied to an enum member; as the word "Field" in this context is misleading.
Upvotes: 0
Reputation: 40603
AttributeTargets.Field allow you to use attribute for enum values.
[AttributeUsage(AttributeTargets.Field)]
Upvotes: 42
Reputation: 71563
Far as I know, there isn't one specifically for enum constants. The closest you could get would probably be "Field", which limits the use to field members of a class or struct (which Enum constants are treated as for purposes of attributes).
EDIT: bringing the explanation of "why" up from the comments, Enum constants are exactly that, and as such their values and usages are embedded directly into the IL. An enum declaration is therefore really not very different from creating a static class definition with static constant members:
public static class MyEnum
{
public const int Value1 = 0;
public const int Value2 = 1;
public const int Value3 = 2;
public const int Value4 = 3;
}
... the only difference being that it derives from System.Enum which is a value type instead of being a reference class (you can't create a static struct, nor an unconstructible one).
Upvotes: 78
Reputation: 185643
There isn't a way to specify that an attribute can be used only on enum members. Honestly, you're probably better off creating your own Effect
(or EffectType
) class and implementing these as ordinary properties if you're going to have multiple attributes like this.
For example,
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);
}
Taking this approach will give you code that's both easier to read and will perform better compared to metadata extraction.
Upvotes: 5