I have some entities created with LINQ-to-SQL. Six of these entities (representing values primarily in drop-down lists) implement an interface I've called IValue
. I did this because the UI layer is going to have to account for a couple special cases -- notably, what to display if the original value on a record has been flagged as deleted.
The repository has a variety of ListAllXXX
methods for these guys. All of these return generic lists typed to the appropriate entity type. An example:
public static List<ContactType> ListAllContactTypes(DeletedOptions getDeleted)
{ /* requisite code */ }
ContactType
does implement IValue
, of course.
There's another set of services designed to actually retrieve the UI-specific list. The basic pattern is thus:
// One of these for each entity type
public static List<IValue> GetContactTypeList(ContactType target)
{
List<IValue> ret = LovRepository.ListAllContactTypes(DeletedOptions.NoDeleted);
PrepList(ret, target);
return ret;
}
// All of the above methods use this 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 probably note that DummyValue
is a simple class I created that also implements IValue
, and whose whole purpose in life is to serve as the "add new" and "deleted" menu options.)
All of this comes about because I didn't want to write a few dozen lines of almost identical code -- the whole reason I thought we had covariance.
The code as written here does not compile. I've tried a manual cast to List<IValue>
on the ListAllContactTypes
line; that compiles, but fails at run-time with an invalid cast exception.
How can I get where I want to go here? Is there a limitation on using generic variance with interfaces? If so, is there an easy way around it? If not, am I relegated to writing a bunch of highly-repetitive-but-just-slightly-different code? (Which I'm really trying to avoid.)
This may well be a duplicate, but my Google-fu is failing me right now. If it is, please vote to close accordingly. (I'll pile on a close vote if that's the case!)