c# - Implementing generic methods from an interface using another interface -


my apologies if bit simplistic after years of python i'm learning first compiled language (c#) , taking on 2 new (to me) methodolgoies: interfaces , generics.

the preamble:

i'm attempting create common interface allow me n methods of interacting database. in case, using sqlite, or perhaps cloud service, or direct connection network database server. want business application able instantiate of connection methodologies , assured interface identical.

the code:

here's simplified version of i'm trying now.

database interface ielement interface define table.

public interface idatabase {     void setitem( ielement task );  //this works fine     list<t> listtasks<t>() t : ielement; // doesn't } 

ielement interface:

public interface ielement {     int id { get; set; } } 

implementation of ielement:

public class taskelement: ielement {     public int id { get; set; }     public string name {get; set; } } 

implementation of idatabase:

public class sqlitedb: idatabase {     public sqlitedb( sqliteconnection conn )     {         database = conn;     }      public void setitem( ielement task )     {         // works fine when passed new taskelement() implementation of ielement.         database.insert( task );      }      //it goes off rails here     public list<t> listitems<t>() t : ielement     {         var returnlist = new list<ielement>          foreach (var s in database.table<taskelement>())         { returnlist.add(s); }          return returnlist;     } 

i've tried lot of variations on each 1 gives me new issue. here, instance, there 2 errors.

1)

the type arguments method 'sqlitedb.listtasks<t>()' cannot inferred usage. try specifying type arguments explicitly.

2)

cannot implicitly convert type 'system.collections.generic.list<taskelement>' 'system.collections.generic.list<t>'

i've tried changing method use explicit type have had issues there. if use ielement (my generic interface elements )i can't return list of taskelement objects (my implementation of ielement) doesn't match return type (list<ielement>) , if change return type list<taskelement> i'm not longer implementing interface.

anyway, suspect i've got large knowledge gap on how generics working despite lot of reading gap remains. it's worth noting can work if stop using interface , generics, seems ideal situation use interface. maybe i'm trying hard cram lot of stuff interface when application (like direct inheritance) might better?

the question:

how can implement interface generic return value while limiting types can returned implementations of interface.

let's closely @ implementation of listitems:

public list<t> listitems<t>() t : ielement {     var returnlist = new list<ielement>      foreach (var s in database.table<taskelement>())     { returnlist.add(s); }      return returnlist; } 

what you've done here written method caller allowed ask type want in list long type implements ielement. code in method doesn't give them list of type want, gives them list of ielement. it's violating contract.

but real root of problem database.table<taskelement>(). can ever give instances of taskelement. need make t, need additional generic constraint:

public list<t> listitems<t>() t : ielement, new {     var returnlist = new list<t>      foreach (var s in database.table<t>())     {          returnlist.add(s);      }      return returnlist; } 

this because database.table<t> has new constraint, means can given types have zero-parameter constructor (because method going create instances of given class).


Comments