C#抽象类多泛型类型问题:派生类构造函数传参类型不匹配
问题分析
你的代码核心问题是泛型类型不匹配:
- 派生类
ProviderClassyChangesProposedThingieSection继承的是ThingieSection<ProviderClassyChangesProposedSummaryThingie>,所以基类构造函数要求的参数是List<Thingie<ProviderClassyChangesProposedSummaryThingie>>,但你传入的是List<Thingie<Classy>>,这两个列表类型不兼容(默认Thingie<T>不支持协变)。 - 你之前尝试拆分双泛型但没解决,是因为没给泛型加正确约束,也没理清泛型参数的对应关系。
解决方案
这里提供两种可行的修正方式:
方式一:让Thingie支持协变(推荐)
把Thingie<T>改成协变接口(C#中类不能做协变,接口可以),这样Thingie<Classy>可以隐式转换为其派生类对应的泛型接口,同时调整ThingieSection的泛型参数为实体类型:
using System.Collections.Generic; // 改成协变接口,out关键字实现协变 public interface IThingie<out T> { string TextStuff { get; } string Generate(); } public abstract class Thingie<T> : IThingie<T> { public string TextStuff { get; private set; } protected Thingie(T workFlowEntity, string category) { // 初始化逻辑 } public abstract string Generate(); } // ThingieSection泛型参数绑定实体类型T public abstract class ThingieSection<T> { public string Title { get; private set; } public string TextStuff { get; private set; } public List<IThingie<T>> Thingies { get; private set; } protected ThingieSection(string title, string textStuff, List<IThingie<T>> thingies) { Title = title; TextStuff = textStuff; Thingies = thingies; } public abstract string Generate(); } // 派生类指定实体类型为Classy public class ProviderClassyChangesProposedThingieSection : ThingieSection<Classy> { public ProviderClassyChangesProposedThingieSection(string title, string content, List<IThingie<Classy>> thingies) : base(title, content, thingies) { } public override string Generate() => throw new System.NotImplementedException(); } public class ProviderClassyChangesProposedSummaryThingie : Thingie<Classy> { public ProviderClassyChangesProposedSummaryThingie(Classy workFlowEntity, string category) : base(workFlowEntity, category) { } public override string Generate() => throw new System.NotImplementedException(); } public abstract partial class Classy { }
方式二:给ThingieSection添加双泛型参数
如果不想改接口,就给ThingieSection两个泛型参数,分别指定实体类型和具体的Thingie派生类,并添加约束:
using System.Collections.Generic; public abstract class Thingie<T> { public string TextStuff { get; private set; } protected Thingie(T workFlowEntity, string category) { } public abstract string Generate(); } // TEntity是实体类型,TThingie是具体Thingie派生类,约束TThingie必须继承自Thingie<TEntity> public abstract class ThingieSection<TEntity, TThingie> where TThingie : Thingie<TEntity> { public string Title { get; private set; } public string TextStuff { get; private set; } public List<TThingie> Thingies { get; private set; } // 构造函数接收List<TThingie>,如需更宽松的List<Thingie<TEntity>>也可调整 protected ThingieSection(string title, string textStuff, List<TThingie> thingies) { Title = title; TextStuff = textStuff; Thingies = thingies; } public abstract string Generate(); } // 派生类指定实体类型Classy、Thingie派生类为ProviderClassyChangesProposedSummaryThingie public class ProviderClassyChangesProposedThingieSection : ThingieSection<Classy, ProviderClassyChangesProposedSummaryThingie> { public ProviderClassyChangesProposedThingieSection(string title, string content, List<ProviderClassyChangesProposedSummaryThingie> thingies) : base(title, content, thingies) { } public override string Generate() => throw new System.NotImplementedException(); } public class ProviderClassyChangesProposedSummaryThingie : Thingie<Classy> { public ProviderClassyChangesProposedSummaryThingie(Classy workFlowEntity, string category) : base(workFlowEntity, category) { } public override string Generate() => throw new System.NotImplementedException(); } public abstract partial class Classy { }
关键说明
- 方式一的协变接口更灵活,允许传入任何继承自
Thingie<Classy>的子类列表; - 方式二的双泛型参数更明确,强制约束Thingie的具体类型,适合需要严格类型检查的场景。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

