【发布时间】:2010-06-10 15:33:31
【问题描述】:
我有一个需要序列化为 EDI 格式的对象。对于这个例子,我们会说它是一辆汽车。汽车可能不是 b/c 选项随时间变化的最佳示例,但对于真实对象,枚举永远不会改变。
我有许多应用了自定义属性的枚举,如下所示。
public enum RoofStyle
{
[DisplayText("Glass Top")]
[StringValue("GTR")]
Glass,
[DisplayText("Convertible Soft Top")]
[StringValue("CST")]
ConvertibleSoft,
[DisplayText("Hard Top")]
[StringValue("HT ")]
HardTop,
[DisplayText("Targa Top")]
[StringValue("TT ")]
Targa,
}
通过扩展方法访问属性:
public static string GetStringValue(this Enum value)
{
// Get the type
Type type = value.GetType();
// Get fieldinfo for this type
FieldInfo fieldInfo = type.GetField(value.ToString());
// Get the stringvalue attributes
StringValueAttribute[] attribs = fieldInfo.GetCustomAttributes(
typeof(StringValueAttribute), false) as StringValueAttribute[];
// Return the first if there was a match.
return attribs.Length > 0 ? attribs[0].StringValue : null;
}
public static string GetDisplayText(this Enum value)
{
// Get the type
Type type = value.GetType();
// Get fieldinfo for this type
FieldInfo fieldInfo = type.GetField(value.ToString());
// Get the DisplayText attributes
DisplayTextAttribute[] attribs = fieldInfo.GetCustomAttributes(
typeof(DisplayTextAttribute), false) as DisplayTextAttribute[];
// Return the first if there was a match.
return attribs.Length > 0 ? attribs[0].DisplayText : value.ToString();
}
有一个自定义的 EDI 序列化程序,它基于 StringValue 属性进行序列化,如下所示:
StringBuilder sb = new StringBuilder();
sb.Append(car.RoofStyle.GetStringValue());
sb.Append(car.TireSize.GetStringValue());
sb.Append(car.Model.GetStringValue());
...
还有一种方法可以从StringValue中获取Enum Value进行反序列化:
car.RoofStyle = Enums.GetCode<RoofStyle>(EDIString.Substring(4, 3))
定义为:
public static class Enums
{
public static T GetCode<T>(string value)
{
foreach (object o in System.Enum.GetValues(typeof(T)))
{
if (((Enum)o).GetStringValue() == value.ToUpper())
return (T)o;
}
throw new ArgumentException("No code exists for type " + typeof(T).ToString() + " corresponding to value of " + value);
}
}
最后,对于 UI,GetDisplayText() 用于显示用户友好的文本。
你怎么看?矫枉过正?有没有更好的办法?还是 Goldie Locks(刚刚好)?
只是想在我将其永久集成到我的个人框架中之前获得反馈。谢谢。
【问题讨论】:
-
感谢所有不同的方法和讨论。这里有很多很棒的信息,我将使用所有这些信息来重构我原来的方法,以获得最大的性能、可重用性和可维护性。再次感谢大家。
标签: c# enums attributes extension-methods