所以我想我可能在我的实现中把事情复杂化了,但我要做的是:
我想要用IRepository
G 213
现在我的问题是,在我的程序中,当我想使用List items =repository.Items.List()时,它不会编译,因为在ItemsTable中,ITable返回IList而不是List的实现。我可以返回IList,但我确实希望使用一个具体的项目列表。
我还能做什么更好的?
public interface ITable
{
IList<IItem> List();
bool Add(IItem item);
bool Delete(long itemId);
bool Find(long itemId);
}
public class ItemsTable : ITable
{
public IList<IItem> List()
{
IList<IItem> items = GetItems(); // GetItems return List<Item>, Item implements IItem.
return items;
}
.....
...
..
}
public class SQLRepository : IRepository
{
ITable items = new ItemsTable();
public ITable Items
{
get { return items; }
}
}
static void Main(string[] args)
{
var repository = new SQLRepository();
List<Item> items = repository.Items.List();
}发布于 2011-10-24 06:45:51
最好的方法是将您的界面更改为:
public interface ITable<TItem>
where TItem : IItem
{
IList<TItem> List();
bool Add(TItem item);
bool Delete(long itemId);
bool Find(long itemId);
}发布于 2011-10-24 07:12:29
我有几句话要跟你说。
首先,仅仅因为定义了映射到的具体类的接口,您就不需要在任何地方使用接口。使用接口列表的目的是限制存储库和对象的用户可以使用的表面积。所以可以自由地返回List<T>而不是IList<T>。
其次&但是,返回任何实现IList<T>的内容都意味着您希望在从存储库获得列表内容之后修改它。现在,这样做可能是不好的和坏的,有很多原因。
如果您的存储库保留了对它返回的列表的引用,那么后续调用者就可以得到您修改过的列表--因此您真的不能保留引用。所以你需要为每个电话建立列表。
如果为每个调用构建列表,则在返回结果之前有效地调用.ToList操作符。
另一种方法是允许调用方决定何时调用.ToList,然后您只需返回一个IEnumerable<T>。
现在,这在许多方面都更好。
它让调用代码知道列表没有被修改,是另一个调用者。它还允许列表对列表的每一次新的迭代进行请求。
因此,我的建议是--不要返回IList<T>或List<T> --而是返回IEnumerable<T>并让调用者调用.ToList()。
发布于 2011-10-24 06:54:33
现在的问题是,在我的程序中,当我想使用List items =repository.Items.List()时,它不会编译,因为在ItemsTable中,ITable返回IList而不是List的实现。我可以返回IList,但我确实希望使用一个具体的项目列表。
井。你不能两者兼得。如果您想使用List<T>,则需要返回一个。您不能创建一个契约,说明任何IList<T>实现都是正常的,然后期望返回一个List<T>。
这种违规行为通常会使未来变得一团糟,因为IList<IItem> List();承诺了一件事,而你希望它能交付其他东西。这就像去加油站订购无铅汽油,期待含铅汽油(它仍然是汽油,但有点铅)。
https://stackoverflow.com/questions/7872049
复制相似问题