C# 类似于 C++/CLI 中的枚举描述属性
C# like enum desciption attributes in C++/CLI
C# 允许使用以下功能来显示用户友好版本的枚举。类型转换器采用描述属性并使用它来生成字符串。这可以在 C++/CLI 中完成吗?据我所见,'public enum class' 不能在枚举成员上具有属性。这意味着我无法为每个枚举定义描述属性内容。如何定义友好名称?
[TypeConverter(typeof(EnumDescriptionConverter))]
public enum MyEnum
{
[Description("Item1")]
Item1,
[Description("Item2")]
Item2,
}
class EnumDescriptionConverter : EnumConverter
{
private Type _enumType;
public EnumDescriptionConverter(Type type)
: base(type)
{
_enumType = type;
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
{
return destType == typeof(string);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destType)
{
String ReturnString = "";
if (_enumType.GetCustomAttributes<FlagsAttribute>().Any())
{
foreach (var val in EnumExtensions.GetIndividualFlags((Enum)value))
{
FieldInfo fi = _enumType.GetField(Enum.GetName(_enumType, val));
DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));
if (ReturnString != "")
ReturnString += " | ";
if (dna != null)
ReturnString += dna.Description;
else
ReturnString += val.ToString();
}
}
else
{
FieldInfo fi = _enumType.GetField(Enum.GetName(_enumType, value));
DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));
if (ReturnString != "")
ReturnString += " | ";
if (dna != null)
ReturnString += dna.Description;
else
ReturnString += value.ToString();
}
return ReturnString;
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType)
{
return srcType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
foreach (FieldInfo fi in _enumType.GetFields())
{
DescriptionAttribute dna =
(DescriptionAttribute)Attribute.GetCustomAttribute(
fi, typeof(DescriptionAttribute));
if ((dna != null) && ((string)value == dna.Description))
return Enum.Parse(_enumType, fi.Name);
}
return Enum.Parse(_enumType, (string)value);
}
}
在进一步研究之后,我求助于以下类型转换器。它只是用 space 替换枚举成员中的下划线。它还可以处理标志。
ref class EnumDescriptionConverter : public System::ComponentModel::EnumConverter
{
private:
System::Type^ _enumType;
public:
EnumDescriptionConverter(System::Type^ type) : System::ComponentModel::EnumConverter(type)
{
_enumType = type;
}
bool CanConvertTo(System::ComponentModel::ITypeDescriptorContext^ context, System::Type^ destType)override
{
return destType == System::String::typeid;
}
System::Object^ ConvertTo(System::ComponentModel::ITypeDescriptorContext^ context, System::Globalization::CultureInfo^ culture, System::Object^ value, System::Type^ destType)override
{
return value->ToString()->Replace("_", " ");
}
bool CanConvertFrom(System::ComponentModel::ITypeDescriptorContext^ context, System::Type^ srcType)override
{
return srcType == System::String::typeid;
}
System::Object^ ConvertFrom(System::ComponentModel::ITypeDescriptorContext^ context, System::Globalization::CultureInfo^ culture, System::Object^ value)override
{
return System::Enum::Parse(_enumType, ((System::String^)value)->Replace(" ", "_")->Replace(",_", ", "));
}
};
枚举定义如下:
[System::ComponentModel::TypeConverter(typeof(EnumDescriptionConverter))]
public enum class MyEnum
{
Item_1, // Appears as 'Item 1' when data bound or in a property grid
Item_2 // Appears as 'Item 2' when data bound or in a property grid
}
您违反了 Stack Overflow 问题的基本规则:您实际上没有包含真正的源代码或确切的错误消息。
此代码在 Visual Studio 2013 年的全新 C++/CLI 控制台应用程序项目中对我来说编译得很好:
using System::ComponentModel::DescriptionAttribute;
public enum class MyEnum
{
[Description("Item1")]
Item1,
[Description("Item2")]
Item2,
};
C# 允许使用以下功能来显示用户友好版本的枚举。类型转换器采用描述属性并使用它来生成字符串。这可以在 C++/CLI 中完成吗?据我所见,'public enum class' 不能在枚举成员上具有属性。这意味着我无法为每个枚举定义描述属性内容。如何定义友好名称?
[TypeConverter(typeof(EnumDescriptionConverter))]
public enum MyEnum
{
[Description("Item1")]
Item1,
[Description("Item2")]
Item2,
}
class EnumDescriptionConverter : EnumConverter
{
private Type _enumType;
public EnumDescriptionConverter(Type type)
: base(type)
{
_enumType = type;
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
{
return destType == typeof(string);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destType)
{
String ReturnString = "";
if (_enumType.GetCustomAttributes<FlagsAttribute>().Any())
{
foreach (var val in EnumExtensions.GetIndividualFlags((Enum)value))
{
FieldInfo fi = _enumType.GetField(Enum.GetName(_enumType, val));
DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));
if (ReturnString != "")
ReturnString += " | ";
if (dna != null)
ReturnString += dna.Description;
else
ReturnString += val.ToString();
}
}
else
{
FieldInfo fi = _enumType.GetField(Enum.GetName(_enumType, value));
DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));
if (ReturnString != "")
ReturnString += " | ";
if (dna != null)
ReturnString += dna.Description;
else
ReturnString += value.ToString();
}
return ReturnString;
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType)
{
return srcType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
foreach (FieldInfo fi in _enumType.GetFields())
{
DescriptionAttribute dna =
(DescriptionAttribute)Attribute.GetCustomAttribute(
fi, typeof(DescriptionAttribute));
if ((dna != null) && ((string)value == dna.Description))
return Enum.Parse(_enumType, fi.Name);
}
return Enum.Parse(_enumType, (string)value);
}
}
在进一步研究之后,我求助于以下类型转换器。它只是用 space 替换枚举成员中的下划线。它还可以处理标志。
ref class EnumDescriptionConverter : public System::ComponentModel::EnumConverter
{
private:
System::Type^ _enumType;
public:
EnumDescriptionConverter(System::Type^ type) : System::ComponentModel::EnumConverter(type)
{
_enumType = type;
}
bool CanConvertTo(System::ComponentModel::ITypeDescriptorContext^ context, System::Type^ destType)override
{
return destType == System::String::typeid;
}
System::Object^ ConvertTo(System::ComponentModel::ITypeDescriptorContext^ context, System::Globalization::CultureInfo^ culture, System::Object^ value, System::Type^ destType)override
{
return value->ToString()->Replace("_", " ");
}
bool CanConvertFrom(System::ComponentModel::ITypeDescriptorContext^ context, System::Type^ srcType)override
{
return srcType == System::String::typeid;
}
System::Object^ ConvertFrom(System::ComponentModel::ITypeDescriptorContext^ context, System::Globalization::CultureInfo^ culture, System::Object^ value)override
{
return System::Enum::Parse(_enumType, ((System::String^)value)->Replace(" ", "_")->Replace(",_", ", "));
}
};
枚举定义如下:
[System::ComponentModel::TypeConverter(typeof(EnumDescriptionConverter))]
public enum class MyEnum
{
Item_1, // Appears as 'Item 1' when data bound or in a property grid
Item_2 // Appears as 'Item 2' when data bound or in a property grid
}
您违反了 Stack Overflow 问题的基本规则:您实际上没有包含真正的源代码或确切的错误消息。
此代码在 Visual Studio 2013 年的全新 C++/CLI 控制台应用程序项目中对我来说编译得很好:
using System::ComponentModel::DescriptionAttribute;
public enum class MyEnum
{
[Description("Item1")]
Item1,
[Description("Item2")]
Item2,
};