1 //---------------------------------------------------------------------
2 // <copyright file="FilteredReadOnlyMetadataCollection.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
11 using System.Collections;
12 using System.Collections.Generic;
13 using System.Collections.ObjectModel;
14 using System.Data.Common;
15 using System.Diagnostics;
16 using System.Reflection;
19 namespace System.Data.Metadata.Edm
21 internal interface IBaseList<T> : IList
23 T this[string identity] { get;}
25 new T this[int index] { get;}
30 #pragma warning disable 1711 // compiler
32 /// Class to filter stuff out from a metadata collection
38 internal class FilteredReadOnlyMetadataCollection<TDerived, TBase> : ReadOnlyMetadataCollection<TDerived>, IBaseList<TBase>
39 where TDerived : TBase
40 where TBase : MetadataItem
44 /// The constructor for constructing a read-only metadata collection to wrap another MetadataCollection.
46 /// <param name="collection">The metadata collection to wrap</param>
47 /// <exception cref="System.ArgumentNullException">Thrown if collection argument is null</exception>
48 /// <param name="predicate">Predicate method which determines membership</param>
49 internal FilteredReadOnlyMetadataCollection(ReadOnlyMetadataCollection<TBase> collection, Predicate<TBase> predicate) : base(FilterCollection(collection, predicate))
51 Debug.Assert(collection != null);
52 Debug.Assert(collection.IsReadOnly, "wrappers should only be created once loading is over, and this collection is still loading");
54 _predicate = predicate;
59 #region Private Fields
60 // The original metadata collection over which this filtered collection is the view
61 private readonly ReadOnlyMetadataCollection<TBase> _source;
62 private readonly Predicate<TBase> _predicate;
68 /// Gets an item from the collection with the given identity
70 /// <param name="identity">The identity of the item to search for</param>
71 /// <returns>An item from the collection</returns>
72 /// <exception cref="System.ArgumentNullException">Thrown if identity argument passed in is null</exception>
73 /// <exception cref="System.NotSupportedException">Thrown if setter is called</exception>
74 public override TDerived this[string identity]
78 TBase item = _source[identity];
81 return (TDerived)item;
83 throw EntityUtil.ItemInvalidIdentity(identity, "identity");
91 /// Gets an item from the collection with the given identity
93 /// <param name="identity">The identity of the item to search for</param>
94 /// <param name="ignoreCase">Whether case is ignore in the search</param>
95 /// <returns>An item from the collection</returns>
96 /// <exception cref="System.ArgumentNullException">Thrown if identity argument passed in is null</exception>
97 /// <exception cref="System.ArgumentException">Thrown if the Collection does not have an item with the given identity</exception>
98 public override TDerived GetValue(string identity, bool ignoreCase)
100 TBase item = _source.GetValue(identity, ignoreCase);
102 if (_predicate(item))
104 return (TDerived)item;
106 throw EntityUtil.ItemInvalidIdentity(identity, "identity");
110 /// Determines if this collection contains an item of the given identity
112 /// <param name="identity">The identity of the item to check for</param>
113 /// <returns>True if the collection contains the item with the given identity</returns>
114 /// <exception cref="System.ArgumentNullException">Thrown if identity argument passed in is null</exception>
115 /// <exception cref="System.ArgumentException">Thrown if identity argument passed in is empty string</exception>
116 public override bool Contains(string identity)
119 if (_source.TryGetValue(identity, false/*ignoreCase*/, out item))
121 return (_predicate(item));
127 /// Gets an item from the collection with the given identity
129 /// <param name="identity">The identity of the item to search for</param>
130 /// <param name="ignoreCase">Whether case is ignore in the search</param>
131 /// <param name="item">An item from the collection, null if the item is not found</param>
132 /// <returns>True an item is retrieved</returns>
133 /// <exception cref="System.ArgumentNullException">if identity argument is null</exception>
134 public override bool TryGetValue(string identity, bool ignoreCase, out TDerived item)
138 if (_source.TryGetValue(identity, ignoreCase, out baseTypeItem))
140 if (_predicate(baseTypeItem))
142 item = (TDerived)baseTypeItem;
149 internal static List<TDerived> FilterCollection(ReadOnlyMetadataCollection<TBase> collection, Predicate<TBase> predicate)
151 List<TDerived> list = new List<TDerived>(collection.Count);
152 foreach (TBase item in collection)
156 list.Add((TDerived)item);
164 /// Get index of the element passed as the argument
166 /// <param name="value"></param>
167 /// <returns></returns>
168 public override int IndexOf(TDerived value)
171 if (_source.TryGetValue(value.Identity, false /*ignoreCase*/, out item))
173 if (_predicate(item))
175 // Since we are gauranteed to have a unique identity per collection, this item must of T Type
176 return base.IndexOf((TDerived)item);
184 #region IBaseList<TBaseItem> Members
186 TBase IBaseList<TBase>.this[string identity]
188 get { return this[identity]; }
191 TBase IBaseList<TBase>.this[int index]
200 /// Get index of the element passed as the argument
202 /// <param name="item"></param>
203 /// <returns></returns>
204 int IBaseList<TBase>.IndexOf(TBase item)
206 if (_predicate(item))
208 return this.IndexOf((TDerived)item);
216 #pragma warning restore 1711