c# - Generic method where T implements Interface<T> -
i'm trying create generic data retrieval process. have works, there part of doesn't seem right , i'm hoping there better way accomplish it.
so idea have classes each table in database, here example of class:
public class cmcgrgrgroup : ifacetsobject<cmcgrgrgroup> { public int grgr_ck { get; set; } public string grgr_name { get; set; } public string grgr_addr1 { get; set; } public ienumerable<cmcgrgrgroup> toobject(datatable table) { return table.asenumerable().select(row => { return new cmcgrgrgroup { grgr_ck = convert.toint32(row["grgr_ck"]), grgr_name = row["grgr_name"].tostring(), grgr_addr1 = row["grgr_addr1"].tostring() }; }); } }
you'll notice class implements interface of own type. interface defines method called toobject
, used convert datatable class of particular type:
public interface ifacetsobject<t> { ienumerable<t> toobject(datatable obj); }
now, here method using execute query:
public ienumerable<t> executequery<t>(string sql, ifacetsobject<t> obj) t : new() { using (var conn = new aseconnection(_conn)) { conn.open(); var cmd = new asecommand(sql, conn); var dt = new datatable(); var da = new asedataadapter(sql, conn); da.fill(dt); return obj.toobject(dt); //this interface method } }
so main question is: how can generic method know t should implement ifacetsobject<t>
? way don't have pass ifacetsobject<t>
parameter. ideally, change return line this:
return t.toobject(dt);
and call this:
var result = executequery<cmcgrgrgroup>(sql).take(5);
instead of this:
var result = executequery<cmcgrgrgroup>(sql, new cmcgrgrgroup()).take(5);
i'll admit i'm not terribly familiar generics yet there may within implementation isn't right.
you can add constraint on executequery method. have one: requiring t newable. you'd declare like:
public ienumerable<t> executequery<t>(string sql, ifacetsobject<t> obj) t : ifacetsobject<t>, new() { using (var conn = new aseconnection(_conn)) { conn.open(); var cmd = new asecommand(sql, conn); var dt = new datatable(); var da = new asedataadapter(sql, conn); da.fill(dt); return obj.toobject(dt); //this interface method } }
so knows t ifacetsobject<t>
. do:
public ienumerable<t> executequery<t>(string sql) t : ifacetsobject<t>, new() { using (var conn = new aseconnection(_conn)) { conn.open(); var cmd = new asecommand(sql, conn); var dt = new datatable(); var da = new asedataadapter(sql, conn); da.fill(dt); return new t().toobject(dt); //this interface method } }
which imo still pretty ugly.
edit response:
note cannot call t.toobject - interface cannot define static method. workaround use of new create new instance of t , call instance method.
Comments
Post a Comment