c# - Avoid having to cast with generics and a list of custom data -
i have following code supporting list of different types :
public enum etype { tint, tstring, tdatetime } public interface icustomtype<out t> { t value { get; } } public abstract class differenttype { protected differenttype(etype type, string mnemonic) { type = type; mnemonic = mnemonic; } public string mnemonic { get; private set; } public etype type { get; private set; } } public class datetimetype : differenttype, icustomtype<datetime> { public datetimetype(datetime value, string mnemonic) : base(etype.tdatetime, mnemonic) { value = value; } public datetime value { get; private set; } } public class inttype : differenttype, icustomtype<int> { public inttype(int value, string mnemonic) : base(etype.tint, mnemonic) { value = value; } public int value { get; private set; } } public class stringtype : differenttype, icustomtype<string> { public stringtype(string value, string mnemonic) : base(etype.tstring, mnemonic) { value = value; } public string value { get; private set; } } public static class utilvalue { public static t getvalue<t>(differenttype customtype) { return ((icustomtype<t>)customtype).value; } } public class testtypes2 { public testtypes2() { var values = new list<differenttype> { getint(), getstring(), getdate() }; foreach (var in values) { switch (i.type) { case etype.tint: int resint = utilvalue.getvalue<int>(i); break; case etype.tstring: string resstring = utilvalue.getvalue<string>(i); break; case etype.tdatetime: datetime resdatetime = utilvalue.getvalue<datetime>(i); break; } } } private datetimetype getdate() { return new datetimetype(new datetime(2000, 1, 1), "mnemonicdate"); } private inttype getint() { return new inttype(5, "mnemonicint"); } private stringtype getstring() { return new stringtype("ok", "mnemonicstring"); } } and avoid cast @ line return ((icustomtype<t>)customtype).value; in utilvalue class, idea how can rid of while still keeping design?
i not sure if cast expensive do? guess most certainly.
visitor-pattern example:
interface idifferenttypevisitor { void visit(datetimetype dt); void visit(stringtype st); } class differenttype { public abstract void accept(idifferenttypevisitor visitor); } class datetimetype : differenttype { public void accept(idifferenttypevisitor visitor) { visitor.visit(this); } } class stringtype : differenttype { public void accept(idifferenttypevisitor visitor) { visitor.visit(this); } } class somevisitor : idifferenttypevisitor { public void visit(datetimetype dt) { //datetime resdatetime = dt.value; or similar } public void visit(stringtype st) { //string resstring = st.value; or similar } } public class testtypes2 { public testtypes2() { var values = new list<differenttype> { /* content */ }; var visitor = new somevisitor(); foreach (var in values) { i.accept(visitor); } } } in c# 4 dynamic it's possible save code adding differenttype:
public void accept(idifferenttypevisitor visitor) { visitor.visit((dynamic)this); } and delete other accept methods. hurts performance looks better ;-)
Comments
Post a Comment