public abstract class OperationBase : IOperation
{
public OperationBase(AppPart appPart)
{
this.appPart = appPart;
}
……
public AppPart AppPart
{
get
{
//protect this appPart from being modified
return (AppPart)appPart.Clone();
}
//set
//{
// appPart = value;
//}
}
……
protected AppPart appPart;
……
}
这样其实不是真正的只读(ReadOnly),只不过对“Clone对象”的修改都不会影响到“源对象”而已。对于简单的对象这样做没有问题,但是如果“大对象”比如集合,要Clone的代价就比较大了,所以我们不简单的返回Clone。我们可以自己设计一个集合让它实现IEnumerable接口,但是内部存储使用一个集合,但是这样又带来一个问题,很多集合的操作我们无法使用了,因为IEnumarable接口提供的方法太少。其实.net2.0提供了一个解决方法——“ReadOnlyCollection”,
An instance of the ReadOnlyCollection generic class is always read-only. A collection that is read-only is simply a collection with a wrapper that prevents modifying the collection; therefore, if changes are made to the underlying collection, the read-only collection reflects those changes.
上面是MSDN的介绍,我们可以看到它不仅是只读的,而且静态实例对于“读操作还是线程安全”,前提是读的同时没有线程去修改该集合内部的集合(正真存储了数据的集合)。ReadOnlyCollection其实只是对普通结合的一个包装,将一些修改的操作屏蔽掉了。Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
A ReadOnlyCollection can support multiple readers concurrently, as long as the collection is not modified.
public class ReadOnlyCollection
ReadOnlyCollection的定义说明它实现了像Ilsit,ICollection这样的接口,但是他们是有修改操作的比如Add,Insert,Remove,如果我们对ReadOnlyCollection的实例做强制类型转换在操作会有什么结果:
ReadOnlyCollection
((IList
如果运行这段代码会报错“Not supported exception”,这说明该集合的实现与一般的集合有所不同,CLR的实现者对这个做了特殊的处理。
最后说一个问题,如何对获得只读集合进行排序?我们无法排序,因为无法操作集合,如果要排序的话只能将集合的元素复制到自己的新集合中,在排序:
readonlyColl.CopyTo(new User[readonlyColl.Count],0);
没有评论:
发表评论