What I have:
I have a class where many of the properties use a specific type of attribute. This class also contains a property which is a nullable enum, and each value of the enum may also be decorated with the same attribute. For example:
// My basic class
public class Upgrade
{
[Abbreviation("name")]
public int string Name { get; set; }
[Abbreviation("opt")]
public bool Optional { get; set; } = true;
[Abbreviation("type")]
public UpgradeType? TypeOfUpgrade { get; set; } = null;
}
// My basic enum
public enum UpgradeType
{
[Abbreviation("fl")]
Full,
[Abbreviation("prt")]
Partial
}
// My basic attribute
public class AbbreviationAttribute: Attribute
{
public string Value{ get; private set; }
public AbbreviationAttribute(string value)
{
Value = value;
}
}
What I'm trying to do:
I'm trying to get the name of each property and it's value. However, if the property is decorated with the AbbreviationAttribute
, the value from the attribute should be used instead. Likewise, if the property is any type of enum, the value should be taken from the enum's AbbreviationAttribute
, if it has one.
So for an object such as this:
Upgrade upgrade = new Upgrade
{
Name = "First Upgrade",
Optional = false,
TypeOfUpgrade = UpgradeType.Full
};
I'd like to output the string:
name=First Upgrade;opt=false;type=fl
How can I achieve this?
What I've tried:
I've can get the attribute from the property, however I'm not sure how to access it from the enum property. So in the above example, I can get the AbbreviationAttribute
from the TypeOfUpgrade
property, but since it's an enum, I need to get the AbbreviationAttribute
from it's value.
string values = string.Empty;
// foreach property
foreach(PropertyInfo pi in this.GetType().GetProperties())
{
// get the attribute from the property, if it exists
AbbreviationAttribute attr = pi.GetCustomAttribute<AbbreviationAttribute>();
if (attr != null)
{
//append the value from the attribute, instead of the property name
values += $"{attr.Value}=";
// if property is an enum (nullable or otherwise)
if (pi.PropertyType.IsEnum || pi.PropertyType.IsNullableEnum())
{
// get the type of enum
Type type = Nullable.GetUnderlyingType(pi.PropertyType);
if (type == null)
{
type = pi.PropertyType;
}
// --------------------------
// Now I have the type of enum, and the value from the PropertyInfo,
// how can I access the AbbreviationAttribute that's on the enum's value?
}
}
}
// helper method
public static bool IsNullableEnum(this Type t)
{
Type u = Nullable.GetUnderlyingType(t);
return (u != null) && u.IsEnum;
}