bov*_*ium 152 .net c# collections code-analysis
代码如下所示:
namespace Test
{
public interface IMyClass
{
List<IMyClass> GetList();
}
public class MyClass : IMyClass
{
public List<IMyClass> GetList()
{
return new List<IMyClass>();
}
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行代码分析时,我得到以下建议.
警告3 CA1002:Microsoft.Design:更改'IMyClass.GetList()'中的'List'以使用Collection,ReadOnlyCollection或KeyedCollection
我应该如何解决这个问题以及这里有什么好的做法?
Gre*_*ech 219
要回答问题的"原因"部分,为什么不这样做List<T>,原因是面向未来和API简单化.
面向未来
List<T>不能通过子类化来轻松扩展; 它旨在快速进行内部实施.你会注意到它上面的方法不是虚拟的,所以不能被覆盖,并且它的Add/ Insert/ Remove操作没有钩子.
这意味着如果您将来需要更改集合的行为(例如,拒绝人们尝试添加的空对象,或者在发生这种情况时执行其他工作,例如更新类状态),则需要更改类型你可以返回一个集合的子集,这将是一个破坏性的接口更改(当然,更改不允许null的事物的语义也可能是一个接口更改,但更新内部类状态的事情不会是).
因此,通过返回可以轻松子类化的类Collection<T>或者诸如的接口IList<T>,ICollection<T>或者IEnumerable<T>您可以将内部实现更改为不同的集合类型以满足您的需求,而不会破坏消费者的代码,因为它仍然可以作为返回他们期待的类型.
API简单
List<T>包含许多有用的操作,例如BinarySearch,Sort等等.但是,如果这是您正在公开的集合,那么很可能您控制列表的语义,而不是消费者.因此,虽然您的班级内部可能需要这些操作,但您班级的消费者不太可能想要(甚至应该)调用它们.
因此,通过提供更简单的集合类或接口,您可以减少API用户看到的成员数量,并使他们更容易使用.
Jon*_*eet 49
我个人会声明它返回一个接口而不是一个具体的集合.如果您真的想要列表访问,请使用IList<T>.否则,考虑ICollection<T>和IEnumerable<T>.
我认为还没有人回答“为什么”部分......所以这里是。“为什么”您“应该”使用 aCollection<T>而不是 aList<T>的原因是因为如果您公开 a List<T>,那么任何可以访问您的对象的人都可以修改列表中的项目。而Collection<T>应该表明您正在制作自己的“添加”、“删除”等方法。
您可能不需要担心它,因为您可能只是为自己(或者可能是几个同事)编写界面代码。这是另一个可能有意义的例子。
如果您有一个公共数组,例如:
public int[] MyIntegers { get; }
Run Code Online (Sandbox Code Playgroud)
您可能会认为,因为只有一个“get”访问器,没有人可以弄乱这些值,但事实并非如此。任何人都可以像这样更改里面的值:
someObject.MyIngegers[3] = 12345;
Run Code Online (Sandbox Code Playgroud)
就个人而言,我只会List<T>在大多数情况下使用。但是,如果您正在设计一个将分发给随机开发人员的类库,并且您需要依赖对象的状态……那么您将需要创建自己的集合并从那里将其锁定: )
| 归档时间: |
|
| 查看次数: |
79995 次 |
| 最近记录: |