【问题的提出】
以Windows系统的文件系统为例,文件系统对象目录(DirectoryInfo)或者文件(FileInfo)都派生自文件系统对象(FileSystemInfo),但在我们实际应用中,可能需要这样:
一个集合IList<FileSystemInfo>能完整的反应某一个目录下的所有的文件和文件夹,一个IList<DirectoryInfo>反应该文件夹下的所有子文件夹,一个IList<FileInfo>反应该文件夹下的所有文件,当我们对文件夹集合或者文件集合进行操作的时候,能动态的响应到所有子对象的集合上。
【问题分析】
在.net的类型定义里,虽然IList<>是一个泛型定义,而DirectoryInfo和FileInfo都是派生自FileSystemInfo,但IList<FileSystemInfo>和IList<FileInfo>与IList<DirectoryInfo>没有任何关系,也就是说,我们不能把一个IList<FileInfo>类型的集合对象或者IList<DirectoryInfo>类型的集合对象转换为IList<FileSystemInfo>类型,因此,简单的把实现需求变成了不可能。
【问题解决】
基于以上需求分析,决定定义一个集合代理类CollectionProxy<TSource, TBase>,该泛型类支持把TBase类型的集合对象转换为TSource类型的集合对象。
【代码实现】
1——
ICollectionEX接口定义
///
<summary>
///
扩展集合接口定义。本类接口定义等同于Collection实现的接口
///
</summary>
///
<typeparam name="T"></typeparam>
public
interface ICollectionEx<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
{
///
<summary>
///
新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
///
</summary>
new
int Count {
get; }
///
<summary>
///
新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
///
</summary>
new
void RemoveAt(
int index);
///
<summary>
///
新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
///
</summary>
new
void Clear();
///
<summary>
///
新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
///
</summary>
new T
this[
int index] {
get;
set; }
///
<summary>
///
新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
///
</summary>
new
bool IsReadOnly {
get; }
}
这个接口只是简单的把IList和ICollection两个集合(以及泛型集合)进行整合,考虑到IList与IList<>、ICollection与ICollection<>之间有方法、属性的冲突,因此,对冲突的属性和方法进行了重新定义,目的仅仅是为了避免在使用这个接口的时候出现歧义还需要再次进行转换
2——
CollectionProxy<T>集合的定义与实现
public
class CollectionProxy<TData> : ICollection<TData>
{
private ICollection<TData> _baseCollection;
protected ICollection<TData> BaseCollection
{
get
{
return
this._baseCollection;
}
}
public CollectionProxy(ICollection<TData> baseCollection)
{
if (baseCollection ==
null)
{
throw
new ArgumentNullException(
"
baseCollection
");
}
this._baseCollection = baseCollection;
}
public
void Add(TData item)
{
this.AddItem(item);
}
protected
virtual
void AddItem(TData item)
{
this.BaseCollection.Add(item);
}
public
void Clear()
{
this.ClearAll();
}
protected
virtual
void ClearAll()
{
this.BaseCollection.Clear();
}
public
bool Contains(TData item)
{
return
this.ContainsItem(item);
}
protected
virtual
bool ContainsItem(TData item)
{
return
this.BaseCollection.Contains(item);
}
public
void CopyTo(TData[] array,
int arrayIndex)
{
this.CopyItemTo(array, arrayIndex);
}
protected
virtual
void CopyItemTo(TData[] array,
int arrayIndex)
{
this.BaseCollection.CopyTo(array, arrayIndex);
}
public
int Count
{
get
{
return
this.BaseCollection.Count;
}
}
public
bool IsReadOnly
{
get
{
return
this.BaseCollection.IsReadOnly;
}
}
public
bool Remove(TData item)
{
return
this.RemoveItem(item);
}
protected
virtual
bool RemoveItem(TData item)
{
return
this.BaseCollection.Remove(item);
}
public IEnumerator<TData> GetEnumerator()
{
return
this.BaseCollection.GetEnumerator();
}
#region ICollection
void ICollection<TData>.Add(TData item)
{
this.AddItem(item);
}
void ICollection<TData>.Clear()
{
this.ClearAll();
}
bool ICollection<TData>.Contains(TData item)
{
return
this.Contains(item);
}
void ICollection<TData>.CopyTo(TData[] array,
int arrayIndex)
{
this.CopyItemTo(array, arrayIndex);
}
int ICollection<TData>.Count
{
get
{
return
this.Count;
}
}
bool ICollection<TData>.IsReadOnly
{
get
{
return
this.IsReadOnly;
}
}
bool ICollection<TData>.Remove(TData item)
{
return
this.RemoveItem(item);
}
#endregion
#region IEnumerable<TData>
IEnumerator<TData> IEnumerable<TData>.GetEnumerator()
{
return
this.GetEnumerator();
}
#endregion
#region IEnumerable
IEnumerator IEnumerable.GetEnumerator()
{
return
this.GetEnumerator();
}
#endregion
}
这个类是一个简单的ICollection<>泛型集合的代理类,目的就是实现一个可控的ICollection<>的集合对象。
3——
集合类CollectionExProxy<TData>
public
class CollectionExProxy<TData> : CollectionProxy<TData>, ICollectionEx<TData>, INotifyPropertyChanged, INotifyCollectionChanged
{
#region 构造函数
public CollectionExProxy(Collection<TData> baseCollection)
:
base(baseCollection)
{
}
protected
new Collection<TData> BaseCollection
{
get
{
return
base.BaseCollection
as Collection<TData>;
}
}
#endregion
#region ICollectionEx<TData>
int ICollectionEx<TData>.Count
{
get
{
return (
this
as IList<TData>).Count;
}
}
void ICollectionEx<TData>.RemoveAt(
int index)
{
(
this
as IList<TData>).RemoveAt(index);
}
void ICollectionEx<TData>.Clear()
{
(
this
as IList<TData>).Clear();
}
TData ICollectionEx<TData>.
this[
int index]
{
get
{
return (
this
as IList<TData>)[index];
}
set
{
(
this
as IList<TData>)[index] = value;
}
}
bool ICollectionEx<TData>.IsReadOnly
{
get
{
return (
this
as IList<TData>).IsReadOnly;
}
}
#endregion
#region IList<TData>
int IList<TData>.IndexOf(TData item)
{
return
this.BaseCollection.IndexOf(item);
}
void IList<TData>.Insert(
int index, TData item)
{
this.BaseCollection.Insert(index, item);
}
void IList<TData>.RemoveAt(
int index)
{
this.BaseCollection.RemoveAt(index);
}
TData IList<TData>.
this[
int index]
{
get
{
return
this.BaseCollection[index];
}
set
{
this.BaseCollection[index] = value;
}
}
#endregion
#region IList
int IList.Add(
object value)
{
return (
this.BaseCollection
as IList).Add(value);
}
void IList.Clear()
{
(
this.BaseCollection
as IList).Clear();
}
bool IList.Contains(
object value)
{
return (
this.BaseCollection
as IList).Contains(value);
}
int IList.IndexOf(
object value)
{
return (
this.BaseCollection
as IList).IndexOf(value);
}
void IList.Insert(
int index,
object value)
{
(
this.BaseCollection
as IList).Insert(index, value);
}
bool IList.IsFixedSize
{
get
{
return (
this.BaseCollection
as IList).IsFixedSize;
}
}
bool IList.IsReadOnly
{
get
{
return (
this.BaseCollection
as IList).IsReadOnly;
}
}
void IList.Remove(
object value)
{
(
this.BaseCollection
as IList).Remove(value);
}
void IList.RemoveAt(
int index)
{
(
this.BaseCollection
as IList).RemoveAt(index);
}
object IList.
this[
int index]
{
get
{
return (
this.BaseCollection
as IList)[index];
}
set
{
(
this.BaseCollection
as IList)[index] = value;
}
}
#endregion
#region ICollection
void ICollection.CopyTo(Array array,
int index)
{
(
this.BaseCollection
as ICollection).CopyTo(array, index);
}
int ICollection.Count
{
get
{
return (
this.BaseCollection
as ICollection).Count;
}
}
bool ICollection.IsSynchronized
{
get
{
return (
this.BaseCollection
as ICollection).IsSynchronized;
}
}
object ICollection.SyncRoot
{
get
{
return (
this.BaseCollection
as ICollection).SyncRoot;
}
}
#endregion
#region 事件处理
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
{
add
{
if (
this.BaseCollection
is INotifyPropertyChanged)
{
(
this.BaseCollection
as INotifyPropertyChanged).PropertyChanged += value;
}
else
{
throw
new InvalidOperationException(
string.Format(
"
{0} is not implement interface {1}.
",
this.BaseCollection.GetType(),
typeof(INotifyPropertyChanged)));
}
}
remove
{
if (
this.BaseCollection
is INotifyPropertyChanged)
{
(
this.BaseCollection
as INotifyPropertyChanged).PropertyChanged -= value;
}
else
{
throw
new InvalidOperationException(
string.Format(
"
{0} is not implement interface {1}.
",
this.BaseCollection.GetType(),
typeof(INotifyPropertyChanged)));
}
}
}
event NotifyCollectionChangedEventHandler INotifyCollectionChanged.CollectionChanged
{
add
{
if (
this.BaseCollection
is INotifyCollectionChanged)
{
(
this.BaseCollection
as INotifyCollectionChanged).CollectionChanged += value;
}
else
{
throw
new InvalidOperationException(
string.Format(
"
{0} is not implement interface {1}.
",
this.BaseCollection.GetType(),
typeof(INotifyCollectionChanged)));
}
}
remove
{
if (
this.BaseCollection
is INotifyCollectionChanged)
{
(
this.BaseCollection
as INotifyCollectionChanged).CollectionChanged -= value;
}
else
{
throw
new InvalidOperationException(
string.Format(
"
{0} is not implement interface {1}.
",
this.BaseCollection.GetType(),
typeof(INotifyCollectionChanged)));
}
}
}
#endregion
}
这个类简单实现ICollectionEx<>这个接口,同时为便于对ObservableCollection<>的扩展,实现了INotifyPropertyChanged结合和INotifyCollectionChanged接口,代码都i很简单。
4——
CollectionProxy<TSource, TBase>类,这个类是目标,解决了需求中提到的问题。TSource和TBase之间可以没有任何的关系。TBase类型与TSource类型之间的转换,默认下是进行强制操作,其它情况下,可以通过在构造函数中传递两对象类型转换委托实现。具体代码如下:
public
class CollectionProxy<TSource, TBase> : ICollectionEx<TSource>
{
#region 构造函数
private ICollectionEx<TBase> _baseCollection;
Func<TSource, TBase> _convertSourceToBaseHandler =
null;
Func<TBase, TSource> _convertBaseToSourceHandler =
null;
public CollectionProxy(Collection<TBase> baseCollection, Func<TSource, TBase> convertSourceToBaseHandler =
null, Func<TBase, TSource> convertBaseToSourceHandler =
null)
:
this(
new CollectionExProxy<TBase>(baseCollection), convertSourceToBaseHandler, convertBaseToSourceHandler)
{
}
public CollectionProxy(ICollectionEx<TBase> baseCollection, Func<TSource, TBase> convertSourceToBaseHandler =
null, Func<TBase, TSource> convertBaseToSourceHandler =
null)
{
if (baseCollection ==
null)
{
throw
new ArgumentNullException(
"
baseCollection
");
}
this._baseCollection = baseCollection;
_convertSourceToBaseHandler = convertSourceToBaseHandler;
_convertBaseToSourceHandler = convertBaseToSourceHandler;
}
#endregion
#region 转换函数
private TSource BaseToSourceHandler(TBase @base)
{
if (
this._convertBaseToSourceHandler !=
null)
{
return
this._convertBaseToSourceHandler(@base);
}
return
this.BaseToSourceHandlerInternal(@base);
}
protected
virtual TSource BaseToSourceHandlerInternal(TBase @base)
{
return (TSource)(
object)@base;
}
private TBase SourceToBaseHandler(TSource source)
{
if (
this._convertBaseToSourceHandler !=
null)
{
return
this._convertSourceToBaseHandler(source);
}
return
this.SourceToBaseHandlerInternal(source);
}
protected
virtual TBase SourceToBaseHandlerInternal(TSource source)
{
return (TBase)(
object)source;
}
#endregion
#region 功能函数
public
void Add(TSource item)
{
int count =
this.Count;
this.InsertItem(count, item);
}
public
void Clear()
{
this.ClearItems();
}
protected
virtual
void ClearItems()
{
this.BaseCollection.Clear();
}
public
bool Contains(TSource item)
{
return
this.BaseCollection.Contains(SourceToBaseHandler(item));
}
public
void CopyTo(TSource[] array,
int index)
{
if (array ==
null)
{
throw
new ArgumentNullException(
"
array
");
}
TBase[] tmp =
new TBase[array.Length];
this.BaseCollection.CopyTo(tmp, index);
for (
int i = index; i < index + (
this._baseCollection
as IList).Count; i++)
{
array[i] = BaseToSourceHandler(tmp[i]);
}
}
public IEnumerator<TSource> GetEnumerator()
{
foreach (
var item
in
this._baseCollection)
{
yield
return BaseToSourceHandler(item);
}
}
public
int IndexOf(TSource item)
{
return
this.IndexOfItem(item);
}
protected
virtual
int IndexOfItem(TSource item)
{
return
this.BaseCollection.IndexOf(SourceToBaseHandler(item));
}
public
void Insert(
int index, TSource item)
{
this.InsertItem(index, item);
}
protected
virtual
int InsertItem(
int index, TSource item)
{
this.BaseCollection.Insert(index, SourceToBaseHandler(item));
return index;
}
private
static
bool IsCompatibleObject(
object value)
{
return ((value
is TSource) || ((value ==
null) && (
default(TSource) ==
null)));
}
public
bool Remove(TSource item)
{
int index =
this.IndexOf(item);
if (index <
0)
{
return
false;
}
this.RemoveItem(index);
return
true;
}
public
void RemoveAt(
int index)
{
this.RemoveItem(index);
}
protected
virtual
void RemoveItem(
int index)
{
this.BaseCollection.RemoveAt(index);
}
protected
virtual
void SetItem(
int index, TSource item)
{
this.BaseCollection[index] = SourceToBaseHandler(item);
}
public
int Count
{
get
{
return
this.BaseCollection.Count;
}
}
protected
virtual TSource GetValue(
int index)
{
return BaseToSourceHandler(
this.BaseCollection[index]);
}
public TSource
this[
int index]
{
get
{
return
this.GetValue(index);
}
set
{
this.SetItem(index, value);
}
}
protected ICollectionEx<TBase> BaseCollection
{
get
{
return
this._baseCollection;
}
}
#endregion
#region ICollectionEx<TSource>
int ICollectionEx<TSource>.Count
{
get
{
return (
this
as IList<TSource>).Count;
}
}
void ICollectionEx<TSource>.RemoveAt(
int index)
{
(
this
as IList<TSource>).RemoveAt(index);
}
void ICollectionEx<TSource>.Clear()
{
(
this
as IList<TSource>).Clear();
}
TSource ICollectionEx<TSource>.
this[
int index]
{
get
{
return (
this
as IList<TSource>)[index];
}
set
{
(
this
as IList<TSource>)[index] = value;
}
}
bool ICollectionEx<TSource>.IsReadOnly
{
get
{
return (
this
as IList<TSource>).IsReadOnly;
}
}
#endregion
#region IList<TSource>
int IList<TSource>.IndexOf(TSource item)
{
return
this.IndexOf(item);
}
void IList<TSource>.Insert(
int index, TSource item)
{
this.Insert(index, item);
}
void IList<TSource>.RemoveAt(
int index)
{
this.RemoveAt(index);
}
TSource IList<TSource>.
this[
int index]
{
get
{
return
this[index];
}
set
{
this[index] = value;
}
}
#endregion
#region ICollection<TSource>
void ICollection<TSource>.Add(TSource item)
{
this.Add(item);
}
void ICollection<TSource>.Clear()
{
this.Clear();
}
bool ICollection<TSource>.Contains(TSource item)
{
return
this.Contains(item);
}
void ICollection<TSource>.CopyTo(TSource[] array,
int arrayIndex)
{
this.CopyTo(array, arrayIndex);
}
int ICollection<TSource>.Count
{
get
{
return
this.Count;
}
}
bool ICollection<TSource>.IsReadOnly
{
get
{
return
this._baseCollection.IsReadOnly;
}
}
bool ICollection<TSource>.Remove(TSource item)
{
return
this.Remove(item);
}
#endregion
#region IEnumerable<TSource>
IEnumerator<TSource> IEnumerable<TSource>.GetEnumerator()
{
return
this.GetEnumerator();
}
#endregion
#region IEnumerable
IEnumerator IEnumerable.GetEnumerator()
{
return
this.GetEnumerator();
}
#endregion
#region IList
int IList.Add(
object value)
{
if (IsCompatibleObject(value))
{
int index =
this.Count;
this.InsertItem(index, (TSource)value);
return index;
}
throw
new InvalidCastException();
}
void IList.Clear()
{
this.Clear();
}
bool IList.Contains(
object value)
{
if (IsCompatibleObject(value))
{
return
this.Contains((TSource)value);
}
return
false;
}
int IList.IndexOf(
object value)
{
if (IsCompatibleObject(value))
{
return
this.IndexOf((TSource)value);
}
return -
1;
}
void IList.Insert(
int index,
object value)
{
if (IsCompatibleObject(value))
{
this.Insert(index, (TSource)value);
}
else
{
throw
new InvalidCastException();
}
}
bool IList.IsFixedSize
{
get
{
return
this.BaseCollection.IsFixedSize;
}
}
bool IList.IsReadOnly
{
get
{
return
this.BaseCollection.IsReadOnly;
}
}
void IList.Remove(
object value)
{
if (IsCompatibleObject(value))
{
this.Remove((TSource)value);
}
else
{
throw
new InvalidCastException();
}
}
void IList.RemoveAt(
int index)
{
this.RemoveAt(index);
}
object IList.
this[
int index]
{
get
{
return
this[index];
}
set
{
if (IsCompatibleObject(value))
{
this[index] = (TSource)value;
}
else
{
throw
new InvalidCastException();
}
}
}
#endregion
#region ICollection
void ICollection.CopyTo(Array array,
int index)
{
TSource[] tmp =
new TSource[array.Length];
this.CopyTo(tmp, index);
for (
int i = index; i < array.Length; i++)
{
array.SetValue(tmp[i], i);
}
}
int ICollection.Count
{
get
{
return
this.Count;
}
}
bool ICollection.IsSynchronized
{
get
{
return
this.BaseCollection.IsSynchronized;
}
}
object ICollection.SyncRoot
{
get
{
return
this.BaseCollection.SyncRoot;
}
}
#endregion
}
这个类在构造的时候
5——
一个对应的只读类ReadOnlyCollectionEx的实现
public
class ReadOnlyCollectionEx<T> : ICollectionEx<T>
{
#region 构造函数
[NonSerialized]
private
object _syncRoot;
private IList<T>[] _lists;
public ReadOnlyCollectionEx(IList<T> list,
params IList<T>[] lists)
{
if (list ==
null)
{
throw
new ArgumentNullException(
"
list
");
}
this._lists =
new IList<T>[lists.Length +
1];
_lists[
0] = list;
for (
int i =
0; i < lists.Length; i++)
{
if (lists[i] ==
null)
{
throw
new ArgumentNullException(
"
lists
",
"
顺序号为 {0} 的对象为空。
".FormatWith(i));
}
_lists[i +
1] = lists[
0];
}
}
#endregion
#region 基本操作
[TargetedPatchingOptOut(
"
Performance critical to inline across NGen image boundaries
")]
public
bool Contains(T value)
{
return
this.ContainsInternal(value);
}
protected
virtual
bool ContainsInternal(T value)
{
return
this.IndexOf(value) >=
0;
}
public
void CopyTo(Array array,
int index)
{
if (array ==
null)
{
throw
new ArgumentNullException(
"
array
");
}
if (array.Rank !=
1)
{
throw
new ArgumentOutOfRangeException(
"
array
",
"
只支持一维数组。
");
}
if (array.GetLowerBound(
0) !=
0)
{
throw
new ArgumentOutOfRangeException(
"
array
",
"
只支持0基数组。
");
}
if (index <
0)
{
throw
new ArgumentOutOfRangeException(
"
index
",
"
不能为负数
");
}
if ((array.Length - index) <
this.Count)
{
throw
new ArgumentOutOfRangeException(
"
array, index
",
"
数组空间不足
");
}
this.CopyToInternal(array, index);
}
protected
virtual
void CopyToInternal(Array array,
int index)
{
for (
int i =
0; i <
this.Count; i++)
{
array.SetValue(
this[i], index + i);
}
}
public
int IndexOf(T value)
{
return
this.IndexOfInternal(value);
}
protected
virtual
int IndexOfInternal(T value)
{
int index =
0;
for (
int i =
0; i <
this._lists.Length; i++)
{
int currentIndex =
this._lists[i].IndexOf(value);
if (currentIndex >=
0)
{
return index + currentIndex;
}
else
{
index +=
this._lists[i].Count;
}
}
return -
1;
}
public
int Count
{
get
{
return
this.CountInternal;
}
}
protected
virtual
int CountInternal
{
[TargetedPatchingOptOut(
"
Performance critical to inline across NGen image boundaries
")]
get
{
int count =
0;
for (
int i =
0; i <
this._lists.Length; i++)
{
count += _lists[i].Count;
}
return count;
}
}
public T
this[
int index]
{
get
{
if (index <
0)
{
throw
new ArgumentOutOfRangeException(
"
index
");
}
return
this.GetDataItem(index);
}
}
protected
virtual T GetDataItem(
int index)
{
int tmp = index;
for (
int i =
0; i <
this._lists.Length; i++)
{
if (tmp <
this._lists[i].Count)
{
return
this._lists[i][tmp];
}
tmp -= _lists[i].Count;
}
throw
new ArgumentOutOfRangeException(
"
index
");
}
public IEnumerator<T> GetEnumerator()
{
return
this.GetEnumeratorInternal();
}
protected
virtual IEnumerator<T> GetEnumeratorInternal()
{
for (
int i =
0; i <
this._lists.Length; i++)
{
for (
int j =
0; j <
this._lists[i].Count; j++)
{
yield
return
this._lists[i][j];
}
}
}
private
static
bool IsCompatibleObject(
object value)
{
return ((value
is T) || ((value ==
null) && (
default(T) ==
null)));
}
protected IList<T>[] Items
{
get
{
return
this._lists;
}
}
#endregion
#region 获取枚举集合操作
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return
this.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return
this.GetEnumerator();
}
#endregion
#region 禁止写操作
void ICollection<T>.Add(T value)
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
void ICollection<T>.Clear()
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
bool ICollection<T>.Remove(T value)
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
void IList<T>.Insert(
int index, T value)
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
void IList<T>.RemoveAt(
int index)
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
#endregion
#region 接口其它实现
void ICollection.CopyTo(Array array,
int index)
{
this.CopyTo(array, index);
}
void ICollection<T>.CopyTo(T[] array,
int index)
{
this.CopyTo(array, index);
}
int IList.Add(
object value)
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
void IList.Clear()
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
bool IList.Contains(
object value)
{
return (ReadOnlyCollectionEx<T>.IsCompatibleObject(value) &&
this.Contains((T)value));
}
int IList.IndexOf(
object value)
{
if (IsCompatibleObject(value))
{
return
this.IndexOf((T)value);
}
return -
1;
}
void IList.Insert(
int index,
object value)
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
void IList.Remove(
object value)
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
void IList.RemoveAt(
int index)
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
bool ICollection<T>.IsReadOnly
{
get
{
return
true;
}
}
T IList<T>.
this[
int index]
{
get
{
return
this[index];
}
set
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
}
bool ICollection.IsSynchronized
{
get
{
return
false;
}
}
object ICollection.SyncRoot
{
get
{
if (
this._syncRoot ==
null)
{
ICollection list =
this._lists
as ICollection;
if (list !=
null)
{
this._syncRoot = list.SyncRoot;
}
else
{
Interlocked.CompareExchange<
object>(
ref
this._syncRoot,
new
object(),
null);
}
}
return
this._syncRoot;
}
}
bool IList.IsFixedSize
{
get
{
return
true;
}
}
bool IList.IsReadOnly
{
get
{
return
true;
}
}
object IList.
this[
int index]
{
[TargetedPatchingOptOut(
"
Performance critical to inline across NGen image boundaries
")]
get
{
return
this[index];
}
set
{
throw
new NotImplementedException(
"
只读集合,禁止操作对象。
");
}
}
#endregion
#region ICollectionEx<T>
int ICollectionEx<T>.Count
{
get
{
return (
this
as IList<T>).Count;
}
}
void ICollectionEx<T>.RemoveAt(
int index)
{
(
this
as IList<T>).RemoveAt(index);
}
void ICollectionEx<T>.Clear()
{
(
this
as IList<T>).Clear();
}
T ICollectionEx<T>.
this[
int index]
{
get
{
return (
this
as IList<T>)[index];
}
set
{
(
this
as IList<T>)[index] = value;
}
}
bool ICollectionEx<T>.IsReadOnly
{
get
{
return (
this
as IList<T>).IsReadOnly;
}
}
#endregion
}
这个类只是简单的实现ICollectionEx接口对象的只读化处理,与系统ReadOnlyCollection<>类不同的是,该类支持多个原始数据集合类的构造,可以把多个原始集合类集成为一个统一的集合类对外提供服务。
在输出数据集合的时候,该类默认按照集合的顺序逐个输出,也就是说,先按照集合排队,再按照子集合内部的顺序输出。基于LINQ的原因,集合的顺序可以任意排列。
【应用示例】
一个前面提到的文件系统的需求的实现:
private Collection<FileSystemInfo> _foldersBase =
new Collection<FileSystemInfo>();
private ICollectionEx<DirectoryInfo> _folders;
public ICollectionEx<DirectoryInfo> Folders
{
get
{
if (
this._folders ==
null)
{
this._folders =
new CollectionProxy<DirectoryInfo, FileSystemInfo>(_foldersBase);
}
return _folders;
}
}
private Collection<FileSystemInfo> _filesBase =
new Collection<FileSystemInfo>();
private ICollectionEx<FileInfo> _files;
public ICollectionEx<FileInfo> Files
{
get
{
if (
this._files ==
null)
{
this._files =
new CollectionProxy<FileInfo, FileSystemInfo>(_filesBase);
}
return _files;
}
}
private ReadOnlyCollectionEx<FileSystemInfo> _children;
public ReadOnlyCollectionEx<FileSystemInfo> Children
{
get
{
if (
this._children ==
null)
{
this._children =
new ReadOnlyCollectionEx<FileSystemInfo>(_foldersBase, _filesBase);
}
return
this._children;
}
}