小编典典

收藏与列表你应该在你的接口上使用什么?

all

代码如下所示:

namespace Test
{
    public interface IMyClass
    {
        List<IMyClass> GetList();
    }

    public class MyClass : IMyClass
    {
        public List<IMyClass> GetList()
        {
            return new List<IMyClass>();
        }
    }
}

当我运行代码分析时,我得到以下建议。

警告 3 CA1002:Microsoft.Design:将“IMyClass.GetList()”中的“List”更改为使用
Collection、ReadOnlyCollection 或 KeyedCollection

我应该如何解决这个问题,这里有什么好的做法?


阅读 122

收藏
2022-08-17

共1个答案

小编典典

要回答关于为什么不的问题的“为什么”部分List<T>,原因是面向未来和 API 的简单性。

面向未来

List<T>没有被设计成通过子类化来轻松扩展;它旨在快速用于内部实现。你会注意到它上面的方法不是虚拟的,因此不能被覆盖,并且它的
// 操作中Add没有钩子InsertRemove

这意味着如果您将来需要更改集合的行为(例如拒绝人们尝试添加的空对象,或者在发生这种情况时执行额外的工作,例如更新您的类状态),那么您需要更改类型集合返回到一个可以子类化的集合,这将是一个破坏性的接口更改(当然,更改诸如不允许
null 之类的语义也可能是接口更改,但诸如更新内部类状态之类的事情不会)。

因此,通过返回可以轻松子类化的类Collection<T>或接口IList<T>ICollection<T>或者IEnumerable<T>您可以将内部实现更改为不同的集合类型以满足您的需求,而不会破坏消费者的代码,因为它仍然可以返回为他们期望的类型。

API 简单性

List<T>包含很多有用的操作,例如BinarySearch,Sort等等。但是,如果这是您要公开的集合,那么您很可能控制列表的语义,而不是消费者。因此,虽然您的班级内部可能需要这些操作,但您班级的消费者不太可能想要(甚至应该)调用它们。

因此,通过提供更简单的集合类或接口,您可以减少 API 用户看到的成员数量,并使他们更易于使用。

2022-08-17