Mr *_*nce 4 c# generics .net-7.0
我有这个类结构(简化):
public class InducingMedium
{
public required string File { get; set; }
}
public class InducingVideo : InducingMedium {}
public class InducingAudio : InducingMedium {}
Run Code Online (Sandbox Code Playgroud)
现在,我想一般实例化特定类型的实例:
public abstract class BaseInducingTests<TMedium>
where TMedium : InducingMedium, new()
{
protected async Task<IEnumerable<TMedium>> CreateInducingMedia(IEnumerable<string> files)
{
return files.Select(file =>
{
// Do some processing...
return new TMedium
{
File = file,
};
});
}
}
public class InducingVideosTests : BaseInducingTests<InducingVideo>
{
}
Run Code Online (Sandbox Code Playgroud)
但在派生类中我收到错误:
'Namespace.InducingVideo' cannot satisfy the 'new()' constraint
on parameter 'TMedium' in the generic class 'Namespace.Tests.BaseInducingTests<TMedium>'
because 'Namespace.InducingVideo' has required members
Run Code Online (Sandbox Code Playgroud)
有什么办法可以在不引入反射的情况下解决这个问题吗?
我对成员感到非常兴奋required,它与可为 null 的类型配合得很好,但现在我发现这有它自己的警告:(
文档中明确提到了这一点:
当类型参数包含 new() 约束时,具有任何必需成员的类型不能用作类型参数。编译器无法强制在通用代码中初始化所有必需的成员。
删除required修饰符或更改通用处理。例如通过ctor提供工厂:
public abstract class BaseInducingTests<TMedium>
where TMedium : InducingMedium
{
private readonly Func<string, TMedium> _init;
public BaseInducingTests(Func<string, TMedium> init)
{
_init = init;
}
protected async Task<IEnumerable<TMedium>> CreateInducingMedia(IEnumerable<string> files)
{
return files.Select(file => _init(file));
}
}
public class InducingVideosTests : BaseInducingTests<InducingVideo>
{
public InducingVideosTests() : base(s => new InducingVideo{File = s})
{
}
}
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以创建一个包装器来支持满足new()约束的类:
public abstract class BaseNewableInducingTests<TMedium> : BaseInducingTests<TMedium>
where TMedium : InducingMedium, new()
{
protected BaseNewableInducingTests() : base(s => new TMedium { File = s })
{
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1220 次 |
| 最近记录: |