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