我知道IList是接口,List是具体类型,但我仍然不知道何时使用每一个。我现在做的是,如果我不需要Sort或FindAll方法,我使用接口。我说的对吗?是否有更好的方法来决定何时使用接口或具体类型?


当前回答

由FxCop检查的微软指南不鼓励在公共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;
    }
}

其他回答

由FxCop检查的微软指南不鼓励在公共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;
    }
}

有一件重要的事情,人们似乎总是忽视:

你可以将一个普通数组传递给接受IList<T>参数的对象,然后你可以调用IList. add(),并将收到一个运行时异常:

未处理异常:系统。NotSupportedException:集合大小固定。

例如,考虑以下代码:

private void test(IList<int> list)
{
    list.Add(1);
}

如果你像下面这样调用它,你会得到一个运行时异常:

int[] array = new int[0];
test(array);

这是因为使用带有IList<T>的普通数组违反了利斯科夫替换原则。

因此,如果你调用IList<T>. add(),你可能需要考虑使用List<T>而不是IList<T>。

在我通常遇到的情况下,我很少直接使用IList。

通常我只是把它用作方法的参数

void ProcessArrayData(IList almostAnyTypeOfArray)
{
    // Do some stuff with the IList array
}

这将允许我对. net框架中的几乎任何数组进行泛型处理,除非它使用IEnumerable而不是IList,这种情况有时会发生。

这实际上取决于你需要什么样的功能。我建议在大多数情况下使用List类。当你需要创建一个自定义数组,其中可能包含一些非常特定的规则,你希望将这些规则封装在一个集合中,这样你就不会重复自己的操作,但仍然希望. net将其识别为一个列表时,IList是最好的选择。

IEnumerable 您应该尝试使用最不特定的类型来满足您的目的。 IEnumerable没有IList那么具体。 当您希望循环遍历集合中的项时,可以使用IEnumerable。

IList IList实现了IEnumerable。 当你需要通过索引访问你的集合,添加和删除元素等时,你应该使用IList。

列表 List实现了IList。

你通常最好使用最通用的可用类型,在这种情况下是IList,甚至更好的是IEnumerable接口,这样你可以在以后方便地切换实现。

然而,在。net 2.0中,有一个恼人的事情——IList没有Sort()方法。您可以使用提供的适配器:

ArrayList.Adapter(list).Sort()