类型不能在generics类型或方法中用作类型参数“T” – 为什么?

我正在尝试从接口inheritance两个不同的模型。 这些模型应该作为List或Collection传递给Method。 现在我收到此错误消息:

The type 'InheritanceTest.FooModel' cannot be used as type parameter 'T' in the generic type or method 'InheritanceTest.Service.DoSomethingWith(System.Collections.Generic.IEnumerable)'. There is no implicit reference conversion from 'InheritanceTest.FooModel' to 'InheritanceTest.IModel'. C:\Work\InheritanceTest\InheritanceTest\Program.cs 14 13 InheritanceTest 

有人可以解释一下,我做错了什么? :d

演示代码:

 interface IModel where T : IModelItem { string Name { get; set; } IEnumerable Items { get; set; } } interface IModelItem { string Name { get; set; } } class FooModel : IModel { public FooModel() { Items = new List(); } public string Name { get; set; } public IEnumerable Items { get; set; } } class FooModelItem : IModelItem { public string Name { get; set; } } class Program { static void Main(string[] args) { var fooLists = new List(); var barLists = new ObservableCollection(); var service = new Service(); service.DoSomethingWith(fooLists); service.DoSomethingWith(barLists); } } class Service { public void DoSomethingWith(IEnumerable list) where T : IModel { foreach (var model in list) { Debug.WriteLine(model.Name); foreach (var item in model.Items) { Debug.WriteLine(item.Name); } } } } 

演示项目可以在GitHub上找到: https : //github.com/SunboX/InheritanceTest/blob/master/InheritanceTest/Program.cs

作为为什么你不能这样做的一个例子,想象一下除了FooModelFooModelItem ,你还有BarModelItem 。 现在让我们说你这样做:

 IModel fooModel = new FooModel(); IModel iModel = fooModel; iModel.Items = new List(new BarModelItem()); FooModelItem fooModelItem = fooModel.Items.First(); 

如果这是有效的代码,你就会遇到麻烦,因为你在最后一行找回的项目实际上不是FooModelItem而是BarModelItem

如果仔细阅读每一行,您将看到唯一可能的错误行是第二行。 这说明了为什么无法将IModel分配给IModel ,即使FooModelItem : IModelItem 。 无法执行该分配正是您的方法调用失败的原因。

您可以查看通用协方差和逆变,以了解在某些情况下如何避免这种情况,尽管在不修改模型的情况下它对您的特定情况没有帮助。