我有一个具有类型约束的类:
public class DataManager<TEntity> : IDisposable where TEntity : LogRecord, new()
{
public TEntity GetRecord()
{
...
}
}
它有一个派生类,它使用ServerLogRecord派生的LogRecord作为TEntity:
public class ServerDataManager : DataManager<ServerLogRecord>
{
}
我想将DataManager的公共函数抽象到一个接口中,所以我可以将它设置为unittestable并将实现与客户端代码分离,并且因为public函数返回TEntity,所以我必须在接口中放置类型约束:
public interface IDataManager<out TEntity> where TEntity : LogRecord, new()
{
TEntity GetRecord();
}
然后我有一个问题,我应该如何声明我的植入类以使其保持通用?我尝试了这个解决方案:
public class DataManager<TEntity> : IDataManager<TEntity>, IDisposable
但是我收到了这个错误:
error CS0314: The type 'TEntity' cannot be used as type parameter 'TEntity' in the generic type or method 'IDataManager<TEntity>'. There is no boxing conversion or type parameter conversion from 'TEntity' to 'LogRecord'.
但重新应用约束有效:
public class DataManager<TEntity> : IDataManager<TEntity>, IDisposable where TEntity : LogRecord, new()
“在实现类中重写类型约束”是保持DataManager通用的唯一方法吗?
答案 0 :(得分:1)
如果我理解了问题,请让类实现接口
public class DataManager<TEntity> : IDataManager<TEntity>, IDisposable { ... }
如果意图不是将实现作为通用实现,那么您拥有实体
public class DataManager : IDataManager<MyClass>, IDisposable { ... }
如果MyClass
满足约束条件。
答案 1 :(得分:0)
在实现接口时,您应该提供将要使用的真实类 在实现中不是通用类型,因为在大多数情况下,您不会调用实现,而是 接口。 考虑这段代码
//Where K is key
//where T is a generic entity which may be a programming language
public interface ICoder<K, T>
{
Task Program();
Task LearnNewLanguage(T Language);
K GetCoderId();
}
和您的实现
public class CoderImplementation<TDbContext> : ICoder<string, ProgrammingLanguage> where TDbContext : DbContext
{
private readonly TDbContext _edu;
public CoderImplemtation(TDbContext edu)
{
_edu = edu;
}
public Task Program()
{
...start programming by 12 to 6
}
public Task LearnNewLanguage(string Name)
{
_edu.AddLanguage(Name);
}
}
通过告知TDbContext
类型为DbContext
,您可以访问DbContext
公开的方法
即使DbContext
未知