Here I was spending some time to learn more about C#, so I decided to look into custom Attributes, and I find them quite useful when assigned to Enums.
So I wrote a few extension methods for Enum's to retrieve such attributes quite easily, like for example: DemoEnum.Value1.GetAttribute<EnumNote>()
.
After a while I thought It would be a nice idea if, every custom Attribute would have a reference to the Enum it was assigned to. Not a bad idea I thought, so I went ahead with this:
First I wrote a base class EnumAttribute
for custom Attributes, who inherits the System.Attribute
class of course. This base class is just a first sketch, and I intent to expand it to specially suit every Type of Enum it will be receiving, but so far this will suffice.
public class EnumAttribute : Attribute
{
public EnumInfo Enum { get; internal set; }
public EnumAttribute(Enum Enum)
{
this.Enum = new EnumInfo(Enum);
}
public class EnumInfo
{
private Enum _value;
private Type _type;
private FieldInfo _details;
public Enum Value { get { return _value; } }
public Type Type { get { return _type; } }
public FieldInfo Details { get { return _details; } }
public EnumInfo(Enum value)
{
_value = value;
_type = value.GetType();
_details = _type.GetField(System.Enum.GetName(_type, value));
}
}
}
Now every custom Attribute would have to inherit from this class EnumAttribute
. Resulting for example in a class like EnumNote
:
public class EnumNote : EnumAttribute
{
private string _note = string.Empty;
public string Note { get { return _note; } }
public EnumNote(Enum Enum, string Note)
: base(Enum)
{
_note = Note;
}
}
So far all is good, Visual Studio code analysis and compiler report nothing.
But when I define a Enum like for example:
public enum DemoEnum
{
[EnumNote(DemoEnum.Value1, "Some special note about Enum Value1.")]
Value1 = 1,
[EnumNote(DemoEnum.Value2, "Some other special note about Enum Value2.")]
Value2 = 2
}
And when I try to compile it, VS reports on the first argument of each EnumNote
constructor the following:
An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.
Basically is saying that DemoEnum.Value1 and DemoEnum.Value2 don't hold a constant value. I'm I right?
Any way, this error has me puzzled because this Enum is hard-coded, and as you see the compiler won't even have to assign a value to each enum since I already did it myself.
This of course brings the question, what I'm missing or mis-interpreting, and how should I go about accomplishing the goal of providing a reference to the enum where each EnumNote
is being assigned to?
Thank you.
Update:
After a fresh look at it, I understand why VS reports the enums aren't a constant expression, thats because I'm referring something: DemoEnum.Value1
in a point, where he hasn't finished going through the DemoEnum
to give a definition to Value1
in the first place. However no ideas on how to go ahead with this idea of mine.
Update 2:
What about refactoring the Enum after it has been compiled, it probably shouldn't give any errors then, unless it can't be applied to enums (can't remember if refactoring works with enums), but if it can be applied it will probably be messy to do and slow right?
Update 3: Reason why the Attributes contain reference to the Enum they were assigned to.
It's a pretty simple reason actually, assume the following scenario. Lets say I have a collection of custom Attributes, and for some reason I require at some point to know to which Enum a given Attribute belongs to.
Instead of writing new code to determine that, why not simply reference the given Enum in the Attribute itself? It's a tiny compromise of memory expended, while in the future it would save valuable time running any required process to determine the given Enum of each Attribute (or even just one).