У меня есть объект, который нужно сериализовать в формат EDI.Для этого примера мы скажем, что это автомобиль.Автомобиль может быть не лучшим примером того, как опции b / c меняются со временем, но для реального объекта Enums никогда не изменится.
У меня есть много перечислений, таких как следующие, с применением пользовательских атрибутов.
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());
...
Существует еще один метод, который может получить значение Enum из StringValue для десериализации:
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);
}
}
И, наконец, для пользовательского интерфейса GetDisplayText()
используется для отображения удобного для пользователя текста.
Что вы думаете?Overkill?Есть ли способ лучше?или Голди Локс (просто верно)?
Просто хочу получить обратную связь, прежде чем я навсегда интегрирую ее в свою личную структуру.Благодарю.