Enums C+中类似于枚举描述属性的C+/CLI
C#允许以下功能显示用户友好的Enum版本。类型转换器接受description属性并使用它生成字符串。这可以在C++/CLI中完成吗?据我所见,“公共枚举类”不能在枚举成员上具有属性。这意味着我不能为每个枚举定义描述属性内容。如何定义友好名称Enums C+中类似于枚举描述属性的C+/CLI,enums,c++-cli,Enums,C++ Cli,C#允许以下功能显示用户友好的Enum版本。类型转换器接受description属性并使用它生成字符串。这可以在C++/CLI中完成吗?据我所见,“公共枚举类”不能在枚举成员上具有属性。这意味着我不能为每个枚举定义描述属性内容。如何定义友好名称 [TypeConverter(typeof(EnumDescriptionConverter))] public enum MyEnum { [Description("Item1")] Item1, [Description("
[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);
}
}
[TypeConverter(typeof(EnumDescriptionConverter))]
公共枚举髓鞘
{
[说明(“第1项”)]
项目1,
[说明(“第2项”)]
项目2,
}
类EnumDescriptionConverter:EnumConverter
{
私有类型_enumType;
公共EnumDescriptionConverter(类型)
:基本(类型)
{
_枚举类型=类型;
}
公共覆盖布尔CanConvertTo(ITypeDescriptorContext上下文,类型destType)
{
返回destType==typeof(字符串);
}
公共重写对象转换为(ITypeDescriptorContext上下文,CultureInfo区域性,对象值,类型destType)
{
字符串ReturnString=“”;
if(_enumType.GetCustomAttributes().Any())
{
foreach(EnumExtensions.GetIndividualFlags((Enum)值)中的var val)
{
FieldInfo fi=_enumType.GetField(Enum.GetName(_enumType,val));
DescriptionAttribute dna=(DescriptionAttribute)属性.GetCustomAttribute(fi,typeof(DescriptionAttribute));
如果(返回字符串!=“”)
ReturnString+=“|”;
如果(dna!=null)
ReturnString+=dna.Description;
其他的
ReturnString+=val.ToString();
}
}
其他的
{
FieldInfo fi=_enumType.GetField(Enum.GetName(_enumType,value));
DescriptionAttribute dna=(DescriptionAttribute)属性.GetCustomAttribute(fi,typeof(DescriptionAttribute));
如果(返回字符串!=“”)
ReturnString+=“|”;
如果(dna!=null)
ReturnString+=dna.Description;
其他的
ReturnString+=value.ToString();
}
返回字符串;
}
公共覆盖布尔CanConvertFrom(ITypeScriptorContext上下文,类型srcType)
{
返回srcType==typeof(字符串);
}
公共重写对象ConvertFrom(ITypeDescriptorContext上下文、CultureInfo区域性、对象值)
{
foreach(在_enumType.GetFields()中的FieldInfo fi)
{
描述属性dna=
(DescriptionAttribute)Attribute.GetCustomAttribute(
fi,类型(描述属性));
if((dna!=null)&&((字符串)值==dna.Description))
返回Enum.Parse(_enumType,fi.Name);
}
返回Enum.Parse(_enumType,(string)值);
}
}
在进一步研究之后,我求助于下面的类型转换器。它只是将枚举成员中的下划线替换为空格。它还可以处理标志
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
}
您已经打破了堆栈溢出问题的基本规则:您实际上没有包含真正的源代码或确切的错误消息 这段代码在Visual Studio 2013的全新C++/CLI控制台应用程序项目中编译得非常好:
using System::ComponentModel::DescriptionAttribute;
public enum class MyEnum
{
[Description("Item1")]
Item1,
[Description("Item2")]
Item2,
};
C++11对C++/CLI不是很友好,它采用了
enum类
。[Description]属性仍在编译,但IntelliSense解析器无法处理它们。否则,在数组^lookup=gcnew数组{“foo”、“bar”、“baz}中进行简单查找
您的实际代码是否确实包含公共枚举类
,而不仅仅是枚举类
?前者是C++/CLI maanged类型,后者是C++11作用域的枚举。这不适合我编译。Intellisense突出显示开始括号[
,并给出消息“错误:需要一个标识符。”@RussellTrahan:您是使用/clr
编译的吗?什么版本的Visual Studio?编译器错误是什么?Intellisense不是后台编译,它是一个源代码浏览器,用于处理无法编译的代码,因为代码仍在编辑中。请仅信任实际的编译器错误。确定。它确实编译,但提供Intellisensese错误。我正在使用/clr和VS2013。如果它是有效代码,为什么intellisense会不喜欢它?@RussellTrahan:Hans告诉过你有一个intellisense bug什么,大约3个小时前?当你碰巧看到“非法使用此类型作为表达式”错误时,请确保你没有使用类型(EnumDescriptionConverter)
但是枚举描述转换器::类型ID
。