我有一个类,其中许多属性使用特定类型的属性。此类还包含一个可为空的枚举的属性,并且枚举的每个值也可以使用相同的属性修饰。例如:
// 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;
}
}
我正在尝试获取每个属性的名称及其值。但是,如果属性用AbbreviationAttribute
装饰,则应改用属性中的值。同样,如果属性是任何类型的枚举,则该值应从枚举的AbbreviationAttribute
(如果有)获取。
对于这样的对象:
Upgrade upgrade = new Upgrade
{
Name = "First Upgrade",
Optional = false,
TypeOfUpgrade = UpgradeType.Full
};
我想输出字符串:
name =首次升级; opt = false; type = fl
我该如何实现?
我可以从属性中获取属性,但是我不确定如何从枚举属性中访问它。因此,在上面的示例中,我可以从AbbreviationAttribute
属性中获取TypeOfUpgrade
,但是由于它是一个枚举,因此我需要从其值中获取AbbreviationAttribute
。
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;
}
答案 0 :(得分:0)
枚举值是枚举类型的静态字段。
因此,一旦有了枚举值,就可以获取枚举类型的Type
,获取枚举值的字段信息,并从成员信息中获取属性。
public static TAttributeType GetEnumValueAttribute<TAttributeType>(Enum val)
where TAttributeType : Attribute
{
if (val == null)
{
return null;
}
return
val.GetType().
GetMember(val.ToString())?.
FirstOrDefault()?.
GetCustomAttribute<TAttributeType>();
}
在您的循环中:
foreach (PropertyInfo pi in obj.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())
{
values += $"{GetEnumValueAttribute<AbbreviationAttribute>((Enum)pi.GetValue(obj))?.Value};";
}
else
{
values += $"{pi.GetValue(obj)};";
}
}
}
您实际上是要复制this question。我复制了他的代码,但进行了一些现代化。