简而言之,我希望有一些方法可以实现这种API风格:
Repo repo = new Repo();
List<Car> cars = repo.All<Car>();
List<Truck> trucks = repo.All<Truck>();
我有一个Repo
对象,可以从数据库中检索对象。目前它的工作原理如下:
Repo repo = new Repo();
List<Car> cars = repo.Cars.All();
List<Truck> trucks = repo.Trucks.All();
Repo
类的位置是:
class Repo {
List<Car> Cars = new CarRepo();
List<Truck> Trucks = new TruckRepo();
}
CarRepo
和TruckRepo
各包含:
interface IRepo<T> {
List<T> All();
}
class CarRepo : IRepo<Car> {
List<Car> All() => new List<Car>() { };
}
// Same for TruckRepo
不幸的是,如果我想在此模式中添加新的车辆集合,我需要在Repo
对象上创建一个新列表。在这个人为的例子中,这没什么大不了的,但是这个上帝 - Repo
对象在具有许多子回购的应用程序中可能会变得非常大。我更喜欢的是直接Repo
类工具All
。
interface IRepo<T>
{
List<T> All<T>();
}
partial class Repo {}
partial class Repo : IRepo<Car>
{
public List<Car> All<Car>() => new List<Car>() { };
}
partial class Repo : IRepo<Truck>
{
public List<Truck> All<Truck>() => new List<Truck>() { };
}
// Usage:
Repo repo = new Repo();
List<Car> cars = repo.All<Car>();
这会将All<>
方法添加到Repo
,但由于一些我不知道解决方案的问题,它甚至无法编译。
All<>
针对Repo
实施两次,因为类型不会影响实际的方法签名T
中的第二个List<T> All<T>
是多余的List<Car> All<Car>
中,Car
只是撰写T
的另一种方式,而不是指实际的Car
类这是我第一次在C#中钻研适当的仿制药 - 这是否可能?
答案 0 :(得分:5)
这不是要使用的部分类。 partial类的具体用法是在多个文件之间拆分类的功能。
使用泛型时,目的是定义通用的 核心 功能,然后可以由多种具体类型重复使用。
因此,您应该为每种类型创建一个新的具体存储库类。
interface IRepo<T>
{
List<T> All<T>();
}
class CarRepo : IRepo<Car>
{
public List<Car> All<Car>() => new List<Car>() { };
}
class TruckRepo : IRepo<Truck>
{
public List<Truck> All<Truck>() => new List<Truck>() { };
}
public class Truck { }
public class Car { }
答案 1 :(得分:1)
也许这样的方法可以帮助你:
interface IRepo<T>
{
IEnumerable<T> All();
}
class Repo : IRepo<Car>, IRepo<Truck>
{
public IEnumerable<T> All<T>()
{
if (this is IRepo<T>)
return (this as IRepo<T>).All();
throw new NotSupportedException();
}
IEnumerable<Truck> IRepo<Truck>.All() => new List<Truck>(); //Implemented explicitly
IEnumerable<Car> IRepo<Car>.All() => new List<Car>(); //Implemented explicitly
}
执行此操作,您可以根据需要实施尽可能多的IRepo
,并进行repo.All<Type>()
之类的调用。
这样的事情:
var repo = new Repo();
var trucks = repo.All<Truck>();
var cars = repo.All<Car>();
var motors = repo.All<Motorcycle>(); //throws NotSupportedException
答案 2 :(得分:1)
我会考虑使用接口Car
约束repo项本身(Truck
,IRepoItem
等),并使Repo成为{{1的非泛型类方法是通用的,使用项All<T>()
类型的约束可以返回到该接口,例如:All<T>()
示例代码:
All<T>() where T : IRepoItem