C# 无法将泛型类的子类添加到列表中

C# 无法将泛型类的子类添加到列表中,c#,generics,C#,Generics,我有一个抽象的内容类和具体的子类 public abstract class Content public class ContentA : Content public class ContentB : Content public abstract class ContentSource<T> where T : Content public class SourceX : ContentSource<ContentA> public class Sourc

我有一个抽象的
内容
类和具体的子类

public abstract class Content

public class ContentA : Content

public class ContentB : Content
public abstract class ContentSource<T> where T : Content

public class SourceX : ContentSource<ContentA>

public class SourceY : ContentSource<ContentB>
我还有一个抽象的泛型
ContentSource
类和具体的子类

public abstract class Content

public class ContentA : Content

public class ContentB : Content
public abstract class ContentSource<T> where T : Content

public class SourceX : ContentSource<ContentA>

public class SourceY : ContentSource<ContentB>
但这无法编译-我收到一个“无法从SourceX转换为ContentSource”错误

为什么这不起作用?

这可以在C#使用中实现,但必须使用接口作为列表类型:

public interface IContentSource<out T> where T : Content {}
public class SourceX : IContentSource<ContentA> {}
public class SourceY : IContentSource<ContentB> {}

var ContentSources = new List<IContentSource<Content>>
{
    new SourceX(),
    new SourceY(),
};
公共接口IContentSource,其中T:Content{}
公共类SourceX:IContentSource{}
公共类源代码:IContentSource{}
var ContentSources=新列表
{
新的SourceX(),
新SourceY(),
};

这里很好地解释了这一点:

您仍然可以使用抽象类,但列表仍然必须是接口的列表:

public interface IContentSource<out T> where T : Content {}
public abstract class ContentSource<T> : IContentSource<T> where T : Content {}
public class SourceX : ContentSource<ContentA> {}
public class SourceY : ContentSource<ContentB> {}
公共接口IContentSource,其中T:Content{}
公共抽象类ContentSource:IContentSource,其中T:Content{}
公共类SourceX:ContentSource{}
公共类SourceY:ContentSource{}
还有一个很好的解释,解释了为什么类不支持它:

虽然给出了如何让它工作的完美答案,但我会给你一个简单的答案,解释为什么它不工作

在您的示例中,您希望使用多态性来管理从单一类型基类列表中的公共基类派生的不同类型。类似的东西→

public abstract class Base {}
public class DerivedFirst  : Base {}
public class DerivedSecond : Base {}

var first  = new DerivedFirst();
var second = new DerivedSecond(); 
var list   = new List<Base>{first,second}
这是你的箱子。您可以定义将作为类型参数的类

public abstract class Content

public class ContentA : Content

public class ContentB : Content
在这里你定义你的来源

public abstract class ContentSource<T> where T : Content

public class SourceX : ContentSource<ContentA>   

public class SourceY : ContentSource<ContentB>
当然,这是行不通的:)。
最后,请看一下Kobi的答案。

谢谢,这很有帮助!但是如果我添加一个方法,比如
stringgetlocalpath(T content)对于IContentSource接口,我得到一个编译错误“无效差异:类型参数'T'必须是反向有效的”@sean2000,“out”表示“T仅用于输出位置”。您在输入位置使用它,因此无法将
T
用作方法参数?@sean2000,如果将T定义为out,则不能将T用作输入参数。无论如何,这是没有道理的。最好解释一下你想做什么以及你是如何想出这个方案的。我有几个不同的API端点,其中每个端点都由
ContentSource
类表示,并返回
内容的列表。
ContentSource
类有方法
ContentResultSet搜索(查询查询)
(返回搜索结果)和
string GetLocalPath(T content)
(下载内容并返回保存路径)
public class SourceX : N{}  

public class SourceY : O{}

var ContentSources = new List<M>{
    new SourceX(),
    new SourceY(),
};