一尘不染

采集 与清单 您应该在界面上使用什么?

c#

代码如下所示:

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()”中的“列表”更改为使用Collection,ReadOnlyCollection或KeyedCollection

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


阅读 282

收藏
2020-05-19

共1个答案

一尘不染

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

面向未来

List<T>不能通过子类化而易于扩展;它旨在快速实现内部实现。你会发现它的方法不是虚拟的,因此不能被覆盖,并且没有钩到其Add/
Insert/
Remove操作。

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

因此,通过返回,要么可以很容易的子类,如类Collection<T>或接口,例如IList<T>ICollection<T>或者IEnumerable<T>你可以改变你的内部实现是一个不同的集合类型,以满足您的需求,而不破坏消费者的代码,因为它仍然可以为返回他们期望的类型。

API简单性

List<T>包含许多有用的操作,例如BinarySearchSort等等。但是,如果您要公开的是一个集合,则很可能您控制列表的语义,而不是使用者的语义。因此,尽管您的班级内部可能需要这些操作,但是班级的使用者不太可能希望(甚至应该)调用它们。

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

2020-05-19