Wednesday, 7 August 2013

Generics, enums and custom attributes - is it possible?

Generics, enums and custom attributes - is it possible?

Apologies for the amount of code, but it is easier to explain it this way.
I have a custom attribute CustomUserData implemented as follows:
public class CustomUserData : Attribute
{
public CustomUserData(object aUserData)
{
UserData = aUserData;
}
public object UserData { get; set; }
}
and an extension method for enums as:
public static class EnumExtensions
{
public static TAttribute GetAttribute<TAttribute>(this Enum aValue)
where TAttribute : Attribute
{
Type type = aValue.GetType();
string name = Enum.GetName(type, aValue);
return type.GetField(name)
.GetCustomAttributes(false)
.OfType<TAttribute>()
.SingleOrDefault();
}
public static object GetCustomUserData(this Enum aValue)
{
CustomUserData userValue = GetAttribute<CustomUserData>(aValue);
return userValue != null ? userValue.UserData : null;
}
}
I then have a helper class that serializes/deserializes an enum that has
custom data associated with it as follows:
public static class ParameterDisplayModeEnumListHelper
{
public static List<ParameterDisplayModeEnum> FromDatabase(string
aDisplayModeString)
{
//Default behaviour
List<ParameterDisplayModeEnum> result = new
List<ParameterDisplayModeEnum>();
//Split the string list into a list of strings
List<string> listOfDisplayModes = new
List<string>(aDisplayModeString.Split(','));
//Iterate the enum looking for matches in the list
foreach (ParameterDisplayModeEnum displayModeEnum in
Enum.GetValues(typeof (ParameterDisplayModeEnum)))
{
if (listOfDisplayModes.FindIndex(item => item ==
(string)displayModeEnum.GetCustomUserData()) >= 0)
{
result.Add(displayModeEnum);
}
}
return result;
}
public static string ToDatabase(List<ParameterDisplayModeEnum>
aDisplayModeList)
{
string result = string.Empty;
foreach (ParameterDisplayModeEnum listItem in aDisplayModeList)
{
if (result != string.Empty)
result += ",";
result += listItem.GetCustomUserData();
}
return result;
}
}
however this is specific to ParameterDisplayModeEnum and I have a bunch of
enums that I need to treat this way for serialization/deserialization so I
would prefer to have a generic such as:
public static class EnumListHelper<TEnum>
{
public static List<TEnum> FromDatabase(string aDisplayModeString)
{
//Default behaviour
List<TEnum> result = new List<TEnum>();
//Split the string list into a list of strings
List<string> listOfDisplayModes = new
List<string>(aDisplayModeString.Split(','));
//Iterate the enum looking for matches in the list
foreach (TEnum displayModeEnum in Enum.GetValues(typeof (TEnum)))
{
if (listOfDisplayModes.FindIndex(item => item ==
(string)displayModeEnum.GetCustomUserData()) >= 0)
{
result.Add(displayModeEnum);
}
}
return result;
}
public static string ToDatabase(List<TEnum> aDisplayModeList)
{
string result = string.Empty;
foreach (TEnum listItem in aDisplayModeList)
{
if (result != string.Empty)
result += ",";
result += listItem.GetCustomUserData();
}
return result;
}
}
However this will not work as GetCustomUserData() cannot be invoked. Any
suggestions? I cannot change the use of the custom attribute or the use of
the enums. I am looking for a generic way to do the
serialization/deserialization without having to write a concrete list
helper class each time.
All suggestions appreciated.

No comments:

Post a Comment