How do you migrate from a list to a class C# DataContract Serialization? -
how can migrate configuration new class list of bools? used list of bool, list being abused class, each index having specific meaning field.
i want migrate list, class instead acts list serialization purposes, exposes normal fields rest of application.
how can write class listemulator serializes out list, without introducing new xml tags?
old code
namespace { [datacontract] public class configuration { public const string filename = "configuration.xml"; public configuration() { alist = new list<bool>(); aguidlist = new list<guid>(); } [datamember] public list<guid> aguidlist { get; set; } [datamember] public list<bool> alist { get; set; } } }
new code.
namespace { [datacontract] public class configuration { public const string filename = "configuration.xml"; public configuration() { alistemulator = new listemulator(); aguidlist = new list<guid>(); } [datamember] public list<guid> aguidlist { get; set; } [datamember] public listemulator alistemulator { get; set; } } } public class listemulator { public listemulator() { new listemulator(true, true, true, true); } public listemulator(bool item0, bool item1, bool item2, bool item3) { this.isplanned = item0; this.iscompleted = item1; this.isremaining = item2; this.isserial = item3; } public bool isplanned { get; set; } public bool iscompleted { get; set; } public bool isremaining { get; set; } public bool isserial { get; set; } }
the reason list needed, there old migration code needs ported when there 1 element, 2, 3, 4 different defaults each. if weren't fact have existing deployed configuration files in original format, time them named in xml individually. however, need retain current format now. sake of migration i'm wondering how can accomplish above.
one option listemulator
inherit collection<bool>
, , add specific named properties access elements in array, so:
public class listemulator : collection<bool> { const bool isplanneddefault = false; // change appropriate values. const bool iscompleteddefault = false; const bool isremainingdefault = false; const bool isserialdefault = false; void addalldefaults() { // customize code here upgrade old collections fewer 4 elements current 4-element format. if (count < 1) add(isplanneddefault); if (count < 2) add(iscompleteddefault); if (count < 3) add(isremainingdefault); if (count < 4) add(isserialdefault); } public listemulator() { } public listemulator(bool item0, bool item1, bool item2, bool item3) { this.isplanned = item0; this.iscompleted = item1; this.isremaining = item2; this.isserial = item3; } public bool isplanned { { return this.elementatordefault(0, isplanneddefault); } set { addalldefaults(); this[0] = value; } } public bool iscompleted { { return this.elementatordefault(1, iscompleteddefault); } set { addalldefaults(); this[1] = value; } } public bool isremaining { { return this.elementatordefault(2, isremainingdefault); } set { addalldefaults(); this[2] = value; } } public bool isserial { { return this.elementatordefault(3, isserialdefault); } set { addalldefaults(); this[3] = value; } } protected override void insertitem(int index, bool item) { if (index > 3) throw new argumentoutofrangeexception("index > 3"); base.insertitem(index, item); } }
then in configuration
replace list<bool>
listemulator
, keeping old element name:
[datamember] public listemulator alist { get; set; }
because type implements ienumerable<t>
, datacontractserializer
serialize collection rather object properties. (you might want change class name since it's not list emulator @ point.) however, this works if not add initial values collection within default constructor.
another option add surrogate property configuration
handles necessary conversions, , mark listemulator alist
not serialized:
[datacontract] public class configuration { public const string filename = "configuration.xml"; public configuration() { alist = new listemulator(); aguidlist = new list<guid>(); } [datamember] public list<guid> aguidlist { get; set; } [datamember(name = "alist")] bool[] alistarray { { return alist == null ? null : alist.toarray(); } set { alist = new listemulator(value); } } [ignoredatamember] // not serialize property directly public listemulator alist { get; set; } } public class listemulator { const bool isplanneddefault = false; // change appropriate values. const bool iscompleteddefault = false; const bool isremainingdefault = false; const bool isserialdefault = false; public listemulator(ilist<bool> list) { isplanned = list.elementatordefault(0, isplanneddefault); iscompleted = list.elementatordefault(1, iscompleteddefault); isremaining = list.elementatordefault(2, isremainingdefault); isserial = list.elementatordefault(3, isserialdefault); } public listemulator() { new listemulator(true, true, true, true); } public listemulator(bool item0, bool item1, bool item2, bool item3) { this.isplanned = item0; this.iscompleted = item1; this.isremaining = item2; this.isserial = item3; } public bool isplanned { get; set; } public bool iscompleted { get; set; } public bool isremaining { get; set; } public bool isserial { get; set; } public bool[] toarray() { return new[] { isplanned, iscompleted, isremaining, isserial }; } }
both options use following extension method:
public static class listextensions { public static t elementatordefault<t>(this ilist<t> list, int index, t defaultvalue) { if (index < 0) throw new argumentoutofrangeexception(string.format("index = {0}", index)); if (list == null || index >= list.count) return defaultvalue; return list[index]; } }
Comments
Post a Comment