内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用
代码如下所示:
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
有什么好的做法?
List<T>
不是通过继承它而容易扩展的; 它被设计为快速的内部实现。你会发现它的方法不是虚拟的,因此不能被覆盖,并且没有钩到其Add
/ Insert
/ Remove
操作。
这意味着如果将来需要更改集合的行为(例如,要拒绝人们试图添加的空对象,或者在发生这种情况时执行其他工作(例如更新您的类状态),则需要更改类型你将返回一个你可以继承的类,这将是一个突破的接口变化(当然,改变不允许null这样的事情的语义也可能是一个接口变化,但是更新你的内部类的状态不会)。
因此,通过返回一个可轻松子类化的类(如Collection<T>
接口或类似接口)IList<T>
,ICollection<T>
或者IEnumerable<T>
可以将内部实现更改为不同的集合类型以满足您的需求,而不会破坏消费者代码,因为它仍然可以作为他们期待的类型。
API简单
List<T>
包含许多有用的操作,例如BinarySearch
,Sort
等等。但是,如果这是一个您正在公开的集合,那么您可能会控制列表的语义,而不是用户。所以,当你的班级内部可能需要这些操作时,你的班级的消费者不太可能(甚至应该)给他们打电话。
因此,通过提供更简单的集合类或接口,可以减少API用户看到的成员数量,并使其更易于使用。
我会亲自声明它返回一个接口而不是具体的集合。如果你真的想要列表访问,请使用IList<T>
。否则,考虑ICollection<T>
和IEnumerable<T>
。