我知道IList是接口,List是具体类型,但我仍然不知道何时使用每一个.我现在正在做的是如果我不需要使用该接口的Sort或FindAll方法.我对吗?有没有更好的方法来决定何时使用界面或具体类型?
我遵循两条规则:
接受最有效的基本类型
返回您的用户需要的最丰富的类型
因此,在编写采用集合的函数或方法时,不要将其写入List,而是写入IList
另一方面,当从函数返回一个对象时,您希望为用户提供最丰富的操作集,而无需他们进行转换.因此,在这种情况下,如果它在内部是List
由FxCop检查的Microsoft准则不鼓励在公共API中使用List
顺便说一下,我现在几乎总是将一维数组声明为IList
public interface IMyApi { IListGetReadOnlyValues(); } public class MyApiImplementation : IMyApi { public IList GetReadOnlyValues() { List myList = new List (); ... populate list return myList.AsReadOnly(); } } public class MyMockApiImplementationForUnitTests : IMyApi { public IList GetReadOnlyValues() { IList testValues = new int[] { 1, 2, 3 }; return testValues; } }
人们总是忽视一件重要的事情:
您可以将一个普通数组传递给接受IList
参数的东西,然后您可以调用IList.Add()
并接收运行时异常:
Unhandled Exception: System.NotSupportedException: Collection was of a fixed size.
例如,请考虑以下代码:
private void test(IListlist) { list.Add(1); }
如果按如下方式调用,则会出现运行时异常:
int[] array = new int[0]; test(array);
发生这种情况是因为使用IList
违反Liskov替换原则的普通数组.
因此,如果您打电话,IList
您可能需要考虑要求List
而不是IList
.
我同意李的建议,即参加参赛,但不回复.
如果指定返回接口的方法,则意味着您可以在以后更改确切的实现,而无需消费方法.我以为我永远不需要从List
当然,只需要应用于外部可见的方法(即公共方法).我个人甚至在内部代码中使用接口,但是如果你进行重大更改,你可以自己更改所有代码,但这并不是绝对必要的.
IEnumerable 你应该尝试使用适合你目的的最不具体的类型.IEnumerable不如IList特定,当您想循环遍历集合中的项目时,可以使用IEnumerable
IList IList实现IEnumerable当你需要通过索引访问集合,添加和删除元素等时,你应该使用IList.
列表 列表实现IList
最好尽可能使用最低的基本类型.这使您的界面的实现者或您的方法的消费者有机会在幕后使用他们喜欢的任何东西.
对于集合,您应该尽可能使用IEnumerable.这提供了最大的灵活性,但并不总是适合.
如果您在单个方法中工作(或者在某些情况下甚至在单个类或程序集中)并且外面没有人会看到您正在做什么,请使用List的完整性.但是,如果您正在与外部代码交互,例如当您从方法返回列表时,那么您只需要声明接口而不必将自己绑定到特定实现,特别是如果您无法控制谁编译您的之后的代码.如果你开始使用具体的类型并且你决定改为另一个,即使它使用相同的接口,你也会打破其他人的代码,除非你开始使用接口或抽象基类型.