含required成员的类无法满足泛型new()约束,求无反射修复方案
问题与解决方案
问题背景
类结构定义
public class InducingMedium { public required string File { get; set; } } public class InducingVideo : InducingMedium {} public class InducingAudio : InducingMedium {}
泛型测试类实现
public abstract class BaseInducingTests<TMedium> where TMedium : InducingMedium, new() { protected async Task<IEnumerable<TMedium>> CreateInducingMedia(IEnumerable<string> files) { return files.Select(file => { // 一些处理逻辑... return new TMedium { File = file, }; }); } } public class InducingVideosTests : BaseInducingTests<InducingVideo> { }
错误提示
'Namespace.InducingVideo' cannot satisfy the 'new()' constraint on parameter 'TMedium' in the generic class 'Namespace.Tests.BaseInducingTests<TMedium>' because 'Namespace.InducingVideo' has required members
用户需求:有没有无需使用反射的修复方法?原本看好required成员与nullable类型的配合,但现在发现存在这样的局限性。
无需反射的修复方案
方案1:为派生类添加无参数构造函数并初始化required成员
由于基类的required成员会被派生类继承,给派生类添加显式的无参数构造函数并初始化File属性,就能满足new()约束要求。后续CreateInducingMedia方法会覆盖这个初始值,不影响业务逻辑。
public class InducingVideo : InducingMedium { public InducingVideo() { File = string.Empty; // 初始赋值满足required约束,后续会被替换 } } public class InducingAudio : InducingMedium { public InducingAudio() { File = string.Empty; } }
方案2:使用工厂委托替代new()约束
去掉基类的new()泛型约束,改用抽象工厂委托创建实例。这种方式既保留了required成员强制初始化的设计意图,又规避了new()约束的限制,同时更符合开闭原则。
public abstract class BaseInducingTests<TMedium> where TMedium : InducingMedium { // 抽象工厂委托,由派生类实现具体实例创建逻辑 protected abstract Func<string, TMedium> MediumFactory { get; } protected async Task<IEnumerable<TMedium>> CreateInducingMedia(IEnumerable<string> files) { return files.Select(file => { // 一些处理逻辑... return MediumFactory(file); }); } } public class InducingVideosTests : BaseInducingTests<InducingVideo> { // 实现工厂委托,直接初始化required成员 protected override Func<string, InducingVideo> MediumFactory => file => new InducingVideo { File = file }; }
内容的提问来源于stack exchange,提问作者Mr Patience
相关产品推荐
相关产品推荐

