c# - C# OOP:在基具体类中使用带有类型参数的接口
问题描述
我希望标题是对问题的描述,我在表达我要解决的问题时遇到了麻烦。
我正在使用 .NET Core 2.1
在过去 5 年使用 Python 之后,我最近开始在 C# 商店工作,所以我的强类型 oop 有点生疏了。这是我所拥有的以及我正在尝试做的事情:
我是一个基本存储库接口,它为数据库实体定义了基本的 CRUD 功能:
public interface IRepository<TEntity, TPrimaryKey> where TEntity : class
{
TEntity FindById(TPrimaryKey id)
void Create(TEntity entity);
void Delete (TEntity entity);
}
我从这个接口继承来定义我的存储库类实现的接口:
interface IProductRepository : IRepository<Product, int>
{
void SomeProductRepoMethod(int someParam);
}
然后我在我的具体类中实现所有接口方法:
public class ProductRepository : IProductRepository
{
public Product FindById(int id)
{
// lookup
}
public void Create(Product product)
{
// save
}
public void SomeProductRepoMethod(int someParam)
{
// do product repository specific stuff
}
....
}
现在,我想做的事情相当简单。我想添加一个Create
on的重载,IRepository
它需要一个IEnumerable
of TEntity
:
public interface IRepository<TEntity, TPrimaryKey> where TEntity : class
...
void Create(IEnumerable<TEntity> entities);
...
但是我想定义一次重载的实现:所以我想我可以制作一个抽象的基础存储库类来放置上述实现。我面临的问题是我不确定如何甚至是否可以使用我现在拥有的模型干净地做到这一点。我试图创建一个实现的基类,但这意味着将类型参数传递给基类并传递给接口:IRepository
public abstract class BaseRepository<TEntity, TPrimaryKey> : IRepository<TEntity, TPrimaryKey>
{
public abstract TEntity FindById(TPrimaryKey id);
public abstract void Create(TEntity entity);
public abstract void Delete(TEntity entity);
public void Create(IEnumerable<TEntity> entities)
{
foreach(TEntity entity in entities)
{
Create(entity);
}
}
}
然后在我的具体存储库中:
public class ProductRepository : BaseRepository<Product, int>, IProductRepository
{
public override Product FindById(int id)
{
// lookup
}
public override void Create(Product product)
{
// save
}
public void SomeProductRepoMethod(int someParam)
{
// do product repository specific stuff
}
....
}
这对我来说并不安静,因为我在IProductRepository
and中传递了相同类型的参数ProductRepository
。我觉得我很接近但不在那里,我不确定这里的最佳实践方法是什么。如果有人可以提出一种方法,我将非常感谢您的反馈。为帖子的长度道歉,但我觉得我需要清楚地描述我正在尝试做的事情。谢谢!
解决方案
在接口和抽象类中具有相同的类型参数并不是什么大问题。使用您的抽象类解决方案是可以的,除非您ProductRepository
需要从其他类继承。
实际上,有了你的抽象类,你的IRepository
接口就不再需要存在了。只需处理一切BaseRepository
!
这个问题的另一个解决方案是扩展方法。在静态类中,您可以这样写:
public static void Create<TEntity, TPrimaryKey>(this IRepository<TEntity, TPrimaryKey> repo, IEnumerable<TEntity> entities) where TEntity : class {
// do your foreach loop here
}
IRepository
现在您可以像这样在任何实例上调用此方法:
repository.Create(...);
推荐阅读
- c# - 如何将请求标头添加到 Android 上的 vlc 播放器?
- blazor - blazor webassembly 从 api 下载文件
- python - Sklearn:如何使用有效排名模拟带有 make_regression 的数据集
- excel - 在 Google 表格中,Excel 的动态数组 # 运算符是否有等效项?
- c# - WPF 2D 数组到数组堆栈项
- python - 在将一个 HTML 页面的用户输入呈现到另一个页面(jinja,render_template)的情况下,了解烧瓶层次结构
- azure - 在 .NET 中为 Azure AD 和 GSuite 用户配置 SSO
- java - 例外是 java.lang.BootstrapMethodError: java.lang.NoClassDefFoundError: org/springframework/core/ReactiveTypeDescriptor
- excel - 需要一个基于另一个单元格移动电子表格中的数据的公式
- python - 带有文件名的几个文本文件到 csv