Generics 在.NET4中对接口基类型使用协方差?

Generics 在.NET4中对接口基类型使用协方差?,generics,.net-4.0,interface,c#-4.0,covariance,Generics,.net 4.0,Interface,C# 4.0,Covariance,我使用LINQ to SQL创建了一些实体。其中六个实体(主要在下拉列表中表示值)实现了一个我称之为IValue的接口。我这样做是因为UI层必须考虑一些特殊情况——特别是,如果记录上的原始值被标记为已删除,则显示什么 存储库为这些家伙提供了各种listalxxx方法。所有这些都将泛型列表类型化为相应的实体类型。例如: public static List<ContactType> ListAllContactTypes(DeletedOptions getDeleted) { /*

我使用LINQ to SQL创建了一些实体。其中六个实体(主要在下拉列表中表示值)实现了一个我称之为
IValue
的接口。我这样做是因为UI层必须考虑一些特殊情况——特别是,如果记录上的原始值被标记为已删除,则显示什么

存储库为这些家伙提供了各种
listalxxx
方法。所有这些都将泛型列表类型化为相应的实体类型。例如:

public static List<ContactType> ListAllContactTypes(DeletedOptions getDeleted)
{ /* requisite code */ }
(我可能应该注意到,
DummyValue
是我创建的一个简单类,它也实现了
IValue
,它的全部用途是充当“添加新”和“删除”菜单选项。)

所有这些都是因为我不想写几十行几乎相同的代码——这就是我认为我们有协方差的全部原因

此处编写的代码不可编译。我在
ListAllContactTypes
行上尝试了手动转换到
List
;进行编译,但在运行时失败,并出现无效的强制转换异常

我怎样才能到达我想去的地方?对接口使用通用差异是否有限制?如果是这样的话,有没有简单的方法?如果不是的话,我是不是只能写一堆重复性很高但略有不同的代码?(这是我真正想要避免的。)


这很可能是重复的,但我的Google fu现在让我失望了。如果是,请投票相应关闭。(如果是这样的话,我将投赞成票!)

协变和逆变只能用于委托和接口声明,因此您的代码无法工作。但您可以使用强制转换扩展方法强制转换结果,并使代码正常工作:

List<IValue> ret = LovRepository.ListAllContactTypes(DeletedOptions.NoDeleted)
    .Cast<IValue>().ToList();
<>但是你仍然需要考虑原始的引用,在这方面,它应该被允许做:

ContactType contact = listOfContactType[0];  // Woops, element is not ContactType.

您不能这样做,因为列表中的元素是DummyType。谢天谢地,编译器提前救了我们。

你赢了1个internet。明智地使用它!(非常感谢,我真是疯了。)(是的,它就像冠军一样有效!)
List<ContactType> listOfContactType =  // Some method ....
List<IValue> list = listOfContactType; // This line not allowed.
list.Insert(0,new DummyType());
ContactType contact = listOfContactType[0];  // Woops, element is not ContactType.