你无能为力。这只是关于设计界面:
public interface IDbResultSet<T, TCollection>
where TCollection : ICollection<T>
{
TCollection Items { get; }
int TotalRowCount { get; }
}
正如你在上面看到的,整个接口没有定义Items集合类型:它可以是任何实现ICollection<T>的集合。
现在你可以按如下方式实现它:
public class DbResultSet<T, TCollection> : IDbResultSet<T, TCollection>
where TCollection : ICollection<T>
{
public TCollection Items { get; private set; }
public int TotalRowCount { get; private set; }
public DbResultSet(TCollection items, int totalRowCount)
{
// Note that qualifying with "this" is redundant here
// so I've removed it
Items = items;
TotalRowCount = totalRowCount;
}
}
顺便说一句,我建议你将接口和类名从ResultSet 更改为Result 按原样,因为 set 是一个集合没有顺序但集合项是唯一的类型:
public interface IDbResult<T, TCollection>
where TCollection : ICollection<T>
{
TCollection Items { get; }
int TotalRowCount { get; }
}
public class DbResult<T, TCollection> : IDbResultSet<T, TCollection>
where TCollection : ICollection<T>
{
public TCollection Items { get; private set; }
public int TotalRowCount { get; private set; }
public DbResult(TCollection items, int totalRowCount)
{
// Note that qualifying with "this" is redundant here
// so I've removed it
Items = items;
TotalRowCount = totalRowCount;
}
}
因此,您可以将类型化为接口类型的结果公开:
IDbResult<Category, IList<Category>> GetCategories();
一些建议
我看到您甚至想对单个结果使用这种方法:
DbResultSet<Category> GetCategory(int categoryId);
我的建议是你应该将你的结果分成两个家庭:
所以我最终会得到这些接口:
public interface IMultipleDbResult<T, TCollection>
where TCollection : ICollection<T>
{
TCollection Items { get; }
int TotalRowCount { get; }
}
public interface ISingleDbResult<T>
{
T Item { get; }
}
我建议您这样做是因为奇怪的是您知道自己正在通过Id 获得一个类别,并且您可能需要从列表中获取它:
IDbResult<Category, IList<Category>> result = GetCategoryById(389);
Category category = result.Items[0]; // ??????
// vs.
ISingleDbResult<Category> result = GetCategoryById(389);
Category category = result.Item; // Isn't it more elegant?
顺便说一句,我了解您的实际解决方案涉及在两种结果类型上实现更多属性。例如收集数据库查询错误信息或其他有用的数据。
另一方面,我猜你正在实现像TotalRowCount 这样的属性,因为你正在对结果进行分页。例如,可能有 300 个类别,但 Items 属性包含第一页中的 10 个项目。否则,您的推理有一些缺陷,因为 ICollection<T> 的所有实现都已经拥有 Count 属性。
最后,也许对我在网上发布的一些设计模式感兴趣。见Accmulated Result design pattern。