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

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -