c# - Generics, enums and custom attributes - is it possible? -
apologies amount of code, easier explain way.
i have custom attribute customuserdata implemented follows:
public class customuserdata : attribute { public customuserdata(object auserdata) { userdata = auserdata; } public object userdata { get; set; } }
and extension method enums as:
public static class enumextensions { public static tattribute getattribute<tattribute>(this enum avalue) 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 have helper class serializes/deserializes enum has custom data associated follows:
public static class parameterdisplaymodeenumlisthelper { public static list<parameterdisplaymodeenum> fromdatabase(string adisplaymodestring) { //default behaviour list<parameterdisplaymodeenum> result = new list<parameterdisplaymodeenum>(); //split string list list of strings list<string> listofdisplaymodes = new list<string>(adisplaymodestring.split(',')); //iterate enum looking matches in 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 specific parameterdisplaymodeenum , have bunch of enums need treat way serialization/deserialization prefer have generic such as:
public static class enumlisthelper<tenum> { public static list<tenum> fromdatabase(string adisplaymodestring) { //default behaviour list<tenum> result = new list<tenum>(); //split string list list of strings list<string> listofdisplaymodes = new list<string>(adisplaymodestring.split(',')); //iterate enum looking matches in 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 not work getcustomuserdata() cannot invoked. suggestions? cannot change use of custom attribute or use of enums. looking generic way serialization/deserialization without having write concrete list helper class each time.
all suggestions appreciated.
try code:
public static class enumlisthelper { private static void ensureisenum<tenum>() { if (!typeof(tenum).isenum) throw new invalidoperationexception(string.format("the {0} type not enum.", typeof(tenum))); } public static list<tenum> fromdatabase<tenum>(string adisplaymodestring) tenum : struct { ensureisenum<tenum>(); //default behaviour list<tenum> result = new list<tenum>(); //split string list list of strings list<string> listofdisplaymodes = new list<string>(adisplaymodestring.split(',')); //iterate enum looking matches in list foreach (enum displaymodeenum in enum.getvalues(typeof(tenum))) { if (listofdisplaymodes.findindex(item => item == (string)displaymodeenum.getcustomuserdata()) >= 0) { result.add((tenum)(object)displaymodeenum); } } return result; } public static string todatabase<tenum>(list<tenum> adisplaymodelist) tenum : struct { ensureisenum<tenum>(); string result = string.empty; foreach (var listitem in adisplaymodelist.oftype<enum>()) { if (result != string.empty) result += ","; result += listitem.getcustomuserdata(); } return result; } } var fromdatabase = enumlisthelper.fromdatabase<testenum>("test"); enumlisthelper.todatabase(fromdatabase);
update 0
to clear, because cannot restrict generics enum should check type tenum
enum , throw exception if not. when use fromdatabase
method know tenum
enum, , can write code cast enum specified tenum
:
result.add((tenum)(object)displaymodeenum)
in todatabase
method know tenum
enum , can write code convert tenum
enum
type:
adisplaymodelist.oftype<enum>()
Comments
Post a Comment