generics - Using Covariance with an Interface Base Type in .NET 4? -


i have entities created linq-to-sql. 6 of these entities (representing values in drop-down lists) implement interface i've called ivalue. did because ui layer going have account couple special cases -- notably, display if original value on record has been flagged deleted.

the repository has variety of listallxxx methods these guys. of these return generic lists typed appropriate entity type. example:

public static list<contacttype> listallcontacttypes(deletedoptions getdeleted) { /* requisite code */ } 

contacttype implement ivalue, of course.

there's set of services designed retrieve ui-specific list. basic pattern thus:

// 1 of these each entity type public static list<ivalue> getcontacttypelist(contacttype target) {     list<ivalue> ret = lovrepository.listallcontacttypes(deletedoptions.nodeleted);     preplist(ret, target);      return ret; }  // of above methods use guy private static void preplist(list<ivalue> list, ivalue targetentity) {     list.insert(0, new dummyvalue() { description = "add new ... ", id = 0 });      if (targetentity != null && !(list.contains(targetentity))         list.add(new dummyvalue() { description = "[deleted]", id = -1 }); } 

(i should note dummyvalue simple class created implements ivalue, , whole purpose in life serve "add new" , "deleted" menu options.)

all of comes because didn't want write few dozen lines of identical code -- whole reason thought had covariance.

the code written here not compile. i've tried manual cast list<ivalue> on listallcontacttypes line; compiles, fails @ run-time invalid cast exception.

how can want go here? there limitation on using generic variance interfaces? if so, there easy way around it? if not, relegated writing bunch of highly-repetitive-but-just-slightly-different code? (which i'm really trying avoid.)

this may duplicate, google-fu failing me right now. if is, please vote close accordingly. (i'll pile on close vote if that's case!)

co- , contravariance can used on delegate , interface declarations, code won't work. can cast result using cast extension method, , make code work:

list<ivalue> ret = lovrepository.listallcontacttypes(deletedoptions.nodeleted)     .cast<ivalue>().tolist(); 

this casts each element in list , creates new list of ivalue elements.

the reason why need this, has type safety. in example code of course, there no problem. method listallcontacttypes declared return type list<contacttype>. if assign list<ivalue>, can put ivalue in - if other code expects list contain contacttype explicitly, code break. consider example:

list<contacttype> listofcontacttype =  // method .... list<ivalue> list = listofcontacttype; // line not allowed. 

if compiled, able do:

list.insert(0,new dummytype()); 

but still have consider original reference, on should allowed do:

contacttype contact = listofcontacttype[0];  // woops, element not contacttype. 

you can't this, because element in list dummytype. thankfully compiler saved early.


Comments

Popular posts from this blog

Delphi Wmi Query on a Remote Machine -