MemberCollection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Metadata / Edm / MemberCollection.cs / 2 / MemberCollection.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Reflection; 
using System.Text;
using System.Diagnostics; 
 
namespace System.Data.Metadata.Edm
{ 
    /// 
    /// Class representing a collection of member objects
    /// 
    internal sealed class MemberCollection : MetadataCollection 
    {
        // This way this collection works is that it has storage for members on the current type and access to 
        // members in the base types. As of that requirement, MemberCollection has a reference back to the declaring 
        // type that owns this collection. Whenever MemberCollection is asked to do a look by name, it looks at the
        // current collection, if it doesn't find it, then it ask for it from the declaring type's base type's 
        // MemberCollection. Because of this order, members in derived types hide members in the base type if they
        // have the same name. For look up by index, base type members have lower index then current type's members.
        // Add/Update/Remove operations on this collection is only allowed for members owned by this MemberCollection
        // and not allowed for members owned by MemberCollections in the base types. For example, if the caller tries 
        // to remove a member by ordinal which is within the base type's member ordinal range, it throws an exception.
        // Hence, base type members are in a sense "readonly" to this MemberCollection. When enumerating all the 
        // members, the enumeration starts from members in the root type in the inheritance chain. With this special 
        // enumeration requirement, we have a specialized enumerator class for this MemberCollection. See the
        // Enumerator class for details on how it works. 

        #region Constructors
        /// 
        /// Default constructor for constructing an empty collection 
        /// 
        /// The type that has this member collection 
        /// Thrown if the declaring type is null 
        public MemberCollection(StructuralType declaringType)
            : this(declaringType, null) 
        {
        }

        ///  
        /// The constructor for constructing the collection with the given items
        ///  
        /// The type that has this member collection 
        /// The items to populate the collection
        /// Thrown if the declaring type is null 
        public MemberCollection(StructuralType declaringType, IEnumerable items)
            : base(items)
        {
            Debug.Assert(declaringType != null, "This member collection must belong to a declaring type"); 
            _declaringType = declaringType;
        } 
        #endregion 

        #region Fields 
        private StructuralType _declaringType;
        #endregion

        #region Properties 
        /// 
        /// Returns the collection as a readonly collection 
        ///  
        public override System.Collections.ObjectModel.ReadOnlyCollection AsReadOnly
        { 
            get
            {
                return new System.Collections.ObjectModel.ReadOnlyCollection(this);
            } 
        }
 
        ///  
        /// Gets the count on the number of items in the collection
        ///  
        public override int Count
        {
            get
            { 
                return GetBaseTypeMemberCount() + base.Count;
            } 
        } 

        ///  
        /// Gets an item from the collection with the given index
        /// 
        /// The index to search for
        /// An item from the collection 
        /// Thrown if the index is out of the range for the Collection
        /// Always thrown on setter 
        public override EdmMember this[int index] 
        {
            get 
            {
                int relativeIndex = GetRelativeIndex(index);
                if (relativeIndex < 0)
                { 
                    // This means baseTypeMemberCount must be non-zero, so we can safely cast the base type to StructuralType
                    return ((StructuralType)_declaringType.BaseType).Members[index]; 
                } 

                return base[relativeIndex]; 
            }
            set
            {
                throw EntityUtil.OperationOnReadOnlyCollection(); 
            }
        } 
 
        /// 
        /// Gets an item from the collection with the given identity 
        /// 
        /// The identity of the item to search for
        /// An item from the collection
        /// Thrown if identity argument passed in is null 
        /// Thrown if the Collection does not have an item with the given identity
        /// Always thrown on setter 
        public override EdmMember this[string identity] 
        {
            get 
            {
                EdmMember item = null;
                if (!TryGetValue(identity, false, out item))
                { 
                    throw EntityUtil.MemberInvalidIdentity(identity, "identity");
                } 
 
                return item;
            } 
            set
            {
                throw EntityUtil.OperationOnReadOnlyCollection();
            } 
        }
 
        ///  
        /// Adds an item to the collection
        ///  
        /// The item to add to the list
        /// Thrown if member argument is null
        /// Thrown if the member passed in or the collection itself instance is in ReadOnly state
        /// Thrown if the member that is being added already belongs to another MemberCollection 
        /// Thrown if the MemberCollection already contains a member with the same identity
        public override void Add(EdmMember member) 
        { 
            // Make sure the member is valid for the add operation.
            ValidateMemberForAdd(member, "member"); 

            base.Add(member);

            // Fix up the declaring type 
            member.ChangeDeclaringTypeWithoutCollectionFixup(_declaringType);
        } 
 
        /// 
        /// Determines if this collection contains an item of the given identity 
        /// 
        /// The identity of the item to check for
        /// True if the collection contains the item with the given identity
        public override bool ContainsIdentity(string identity) 
        {
            if (base.ContainsIdentity(identity)) 
            { 
                return true;
            } 

            // The item is not in this collection, check the base type member collection
            EdmType baseType = _declaringType.BaseType;
            if (baseType != null && ((StructuralType)baseType).Members.Contains(identity)) 
            {
                return true; 
            } 

            return false; 
        }

        /// 
        /// Find the index of an item 
        /// 
        /// The item whose index is to be looked for 
        /// The index of the found item, -1 if not found 
        public override int IndexOf(EdmMember item)
        { 
            // Try to get it from this collection, if found, then the relative index needs to be added with the number
            // of members in the base type to get the absolute index
            int relativeIndex = base.IndexOf(item);
            if (relativeIndex != -1) 
            {
                return relativeIndex + GetBaseTypeMemberCount(); 
            } 

            // Try to find it in the base type 
            StructuralType baseType = _declaringType.BaseType as StructuralType;
            if (baseType != null)
            {
                return baseType.Members.IndexOf(item); 
            }
 
            return -1; 
        }
 
        /// 
        /// Copies the items in this collection to an array
        /// 
        /// The array to copy to 
        /// The index in the array at which to start the copy
        /// Thrown if array argument is null 
        /// Thrown if the arrayIndex is less than zero 
        /// Thrown if the array argument passed in with respect to the arrayIndex passed in not big enough to hold the MemberCollection being copied
        public override void CopyTo(EdmMember[] array, int arrayIndex) 
        {
            // Check on the array index
            if (arrayIndex < 0)
            { 
                throw EntityUtil.ArgumentOutOfRange("arrayIndex");
            } 
 
            // Check if the array together with the array index has enough room to copy
            int baseTypeMemberCount = GetBaseTypeMemberCount(); 
            if (base.Count + baseTypeMemberCount > array.Length - arrayIndex)
            {
                throw EntityUtil.Argument("arrayIndex");
            } 

            // If the base type has any members, copy those first 
            if (baseTypeMemberCount > 0) 
            {
                ((StructuralType)_declaringType.BaseType).Members.CopyTo(array, arrayIndex); 
            }

            base.CopyTo(array, arrayIndex + baseTypeMemberCount);
        } 

        ///  
        /// Gets an item from the collection with the given identity 
        /// 
        /// The identity of the item to search for 
        /// Whether case is ignore in the search
        /// An item from the collection, null if the item is not found
        /// True an item is retrieved
        /// if identity argument is null 
        public override bool TryGetValue(string identity, bool ignoreCase, out EdmMember item)
        { 
            // See if it's in this collection 
            if (!base.TryGetValue(identity, ignoreCase, out item))
            { 
                // Now go to the parent type to find it
                EdmType baseType = _declaringType.BaseType;
                if (baseType != null)
                { 
                    ((StructuralType)baseType).Members.TryGetValue(identity, ignoreCase, out item);
                } 
            } 

            return item != null; 
        }

        /// 
        /// Get the declared only members of a particular type 
        /// 
        internal ReadOnlyMetadataCollection GetDeclaredOnlyMembers() where T : EdmMember 
        { 
            MetadataCollection newCollection = new MetadataCollection();
            for (int i = 0; i < base.Count; i++) 
            {
                T member = base[i] as T;
                if (member != null)
                { 
                    newCollection.Add(member);
                } 
            } 

            return newCollection.AsReadOnlyMetadataCollection(); 
        }

        /// 
        /// Get the number of members the base type has.  If the base type is not a structural type or has no 
        /// members, it returns 0
        ///  
        /// The number of members in the base type 
        private int GetBaseTypeMemberCount()
        { 
            // The count of members is what in this collection plus base type's member collection
            StructuralType baseType = _declaringType.BaseType as StructuralType;
            if (baseType != null)
            { 
                return baseType.Members.Count;
            } 
 
            return 0;
        } 

        /// 
        /// Gets the index relative to this collection for the given index.  For an index to really refers to something in
        /// the base type, the return value is negative relative to this collection.  For an index refers to something in this 
        /// collection, the return value is positive.  In both cases, it's simply (index) - (base type member count)
        ///  
        /// The relative index 
        private int GetRelativeIndex(int index)
        { 
            int baseTypeMemberCount = GetBaseTypeMemberCount();
            int thisTypeMemberCount = base.Count;

            // Check if the index is in range 
            if (index < 0 || index >= baseTypeMemberCount + thisTypeMemberCount)
            { 
                throw EntityUtil.ArgumentOutOfRange("index"); 
            }
 
            return index - baseTypeMemberCount;
        }

        ///  
        /// Checks if the given member already has a declaring type, if so, throw an exception
        ///  
        /// The member to check for 
        /// The name of the argument from the caller
        private static void ThrowIfItHasDeclaringType(EdmMember member, string argumentName) 
        {
            EntityUtil.GenericCheckArgumentNull(member, argumentName);
            if (member.DeclaringType != null)
            { 
                throw EntityUtil.MemberAlreadyBelongsToType(argumentName);
            } 
        } 

        private void ValidateMemberForAdd(EdmMember member, string argumentName) 
        {
            // Check to make sure the given member is not associated with another type
            ThrowIfItHasDeclaringType(member, argumentName);
 
            // Validate the item with the declaring type.
            _declaringType.ValidateMemberForAdd(member); 
        } 

        #endregion 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Common;
using System.Reflection; 
using System.Text;
using System.Diagnostics; 
 
namespace System.Data.Metadata.Edm
{ 
    /// 
    /// Class representing a collection of member objects
    /// 
    internal sealed class MemberCollection : MetadataCollection 
    {
        // This way this collection works is that it has storage for members on the current type and access to 
        // members in the base types. As of that requirement, MemberCollection has a reference back to the declaring 
        // type that owns this collection. Whenever MemberCollection is asked to do a look by name, it looks at the
        // current collection, if it doesn't find it, then it ask for it from the declaring type's base type's 
        // MemberCollection. Because of this order, members in derived types hide members in the base type if they
        // have the same name. For look up by index, base type members have lower index then current type's members.
        // Add/Update/Remove operations on this collection is only allowed for members owned by this MemberCollection
        // and not allowed for members owned by MemberCollections in the base types. For example, if the caller tries 
        // to remove a member by ordinal which is within the base type's member ordinal range, it throws an exception.
        // Hence, base type members are in a sense "readonly" to this MemberCollection. When enumerating all the 
        // members, the enumeration starts from members in the root type in the inheritance chain. With this special 
        // enumeration requirement, we have a specialized enumerator class for this MemberCollection. See the
        // Enumerator class for details on how it works. 

        #region Constructors
        /// 
        /// Default constructor for constructing an empty collection 
        /// 
        /// The type that has this member collection 
        /// Thrown if the declaring type is null 
        public MemberCollection(StructuralType declaringType)
            : this(declaringType, null) 
        {
        }

        ///  
        /// The constructor for constructing the collection with the given items
        ///  
        /// The type that has this member collection 
        /// The items to populate the collection
        /// Thrown if the declaring type is null 
        public MemberCollection(StructuralType declaringType, IEnumerable items)
            : base(items)
        {
            Debug.Assert(declaringType != null, "This member collection must belong to a declaring type"); 
            _declaringType = declaringType;
        } 
        #endregion 

        #region Fields 
        private StructuralType _declaringType;
        #endregion

        #region Properties 
        /// 
        /// Returns the collection as a readonly collection 
        ///  
        public override System.Collections.ObjectModel.ReadOnlyCollection AsReadOnly
        { 
            get
            {
                return new System.Collections.ObjectModel.ReadOnlyCollection(this);
            } 
        }
 
        ///  
        /// Gets the count on the number of items in the collection
        ///  
        public override int Count
        {
            get
            { 
                return GetBaseTypeMemberCount() + base.Count;
            } 
        } 

        ///  
        /// Gets an item from the collection with the given index
        /// 
        /// The index to search for
        /// An item from the collection 
        /// Thrown if the index is out of the range for the Collection
        /// Always thrown on setter 
        public override EdmMember this[int index] 
        {
            get 
            {
                int relativeIndex = GetRelativeIndex(index);
                if (relativeIndex < 0)
                { 
                    // This means baseTypeMemberCount must be non-zero, so we can safely cast the base type to StructuralType
                    return ((StructuralType)_declaringType.BaseType).Members[index]; 
                } 

                return base[relativeIndex]; 
            }
            set
            {
                throw EntityUtil.OperationOnReadOnlyCollection(); 
            }
        } 
 
        /// 
        /// Gets an item from the collection with the given identity 
        /// 
        /// The identity of the item to search for
        /// An item from the collection
        /// Thrown if identity argument passed in is null 
        /// Thrown if the Collection does not have an item with the given identity
        /// Always thrown on setter 
        public override EdmMember this[string identity] 
        {
            get 
            {
                EdmMember item = null;
                if (!TryGetValue(identity, false, out item))
                { 
                    throw EntityUtil.MemberInvalidIdentity(identity, "identity");
                } 
 
                return item;
            } 
            set
            {
                throw EntityUtil.OperationOnReadOnlyCollection();
            } 
        }
 
        ///  
        /// Adds an item to the collection
        ///  
        /// The item to add to the list
        /// Thrown if member argument is null
        /// Thrown if the member passed in or the collection itself instance is in ReadOnly state
        /// Thrown if the member that is being added already belongs to another MemberCollection 
        /// Thrown if the MemberCollection already contains a member with the same identity
        public override void Add(EdmMember member) 
        { 
            // Make sure the member is valid for the add operation.
            ValidateMemberForAdd(member, "member"); 

            base.Add(member);

            // Fix up the declaring type 
            member.ChangeDeclaringTypeWithoutCollectionFixup(_declaringType);
        } 
 
        /// 
        /// Determines if this collection contains an item of the given identity 
        /// 
        /// The identity of the item to check for
        /// True if the collection contains the item with the given identity
        public override bool ContainsIdentity(string identity) 
        {
            if (base.ContainsIdentity(identity)) 
            { 
                return true;
            } 

            // The item is not in this collection, check the base type member collection
            EdmType baseType = _declaringType.BaseType;
            if (baseType != null && ((StructuralType)baseType).Members.Contains(identity)) 
            {
                return true; 
            } 

            return false; 
        }

        /// 
        /// Find the index of an item 
        /// 
        /// The item whose index is to be looked for 
        /// The index of the found item, -1 if not found 
        public override int IndexOf(EdmMember item)
        { 
            // Try to get it from this collection, if found, then the relative index needs to be added with the number
            // of members in the base type to get the absolute index
            int relativeIndex = base.IndexOf(item);
            if (relativeIndex != -1) 
            {
                return relativeIndex + GetBaseTypeMemberCount(); 
            } 

            // Try to find it in the base type 
            StructuralType baseType = _declaringType.BaseType as StructuralType;
            if (baseType != null)
            {
                return baseType.Members.IndexOf(item); 
            }
 
            return -1; 
        }
 
        /// 
        /// Copies the items in this collection to an array
        /// 
        /// The array to copy to 
        /// The index in the array at which to start the copy
        /// Thrown if array argument is null 
        /// Thrown if the arrayIndex is less than zero 
        /// Thrown if the array argument passed in with respect to the arrayIndex passed in not big enough to hold the MemberCollection being copied
        public override void CopyTo(EdmMember[] array, int arrayIndex) 
        {
            // Check on the array index
            if (arrayIndex < 0)
            { 
                throw EntityUtil.ArgumentOutOfRange("arrayIndex");
            } 
 
            // Check if the array together with the array index has enough room to copy
            int baseTypeMemberCount = GetBaseTypeMemberCount(); 
            if (base.Count + baseTypeMemberCount > array.Length - arrayIndex)
            {
                throw EntityUtil.Argument("arrayIndex");
            } 

            // If the base type has any members, copy those first 
            if (baseTypeMemberCount > 0) 
            {
                ((StructuralType)_declaringType.BaseType).Members.CopyTo(array, arrayIndex); 
            }

            base.CopyTo(array, arrayIndex + baseTypeMemberCount);
        } 

        ///  
        /// Gets an item from the collection with the given identity 
        /// 
        /// The identity of the item to search for 
        /// Whether case is ignore in the search
        /// An item from the collection, null if the item is not found
        /// True an item is retrieved
        /// if identity argument is null 
        public override bool TryGetValue(string identity, bool ignoreCase, out EdmMember item)
        { 
            // See if it's in this collection 
            if (!base.TryGetValue(identity, ignoreCase, out item))
            { 
                // Now go to the parent type to find it
                EdmType baseType = _declaringType.BaseType;
                if (baseType != null)
                { 
                    ((StructuralType)baseType).Members.TryGetValue(identity, ignoreCase, out item);
                } 
            } 

            return item != null; 
        }

        /// 
        /// Get the declared only members of a particular type 
        /// 
        internal ReadOnlyMetadataCollection GetDeclaredOnlyMembers() where T : EdmMember 
        { 
            MetadataCollection newCollection = new MetadataCollection();
            for (int i = 0; i < base.Count; i++) 
            {
                T member = base[i] as T;
                if (member != null)
                { 
                    newCollection.Add(member);
                } 
            } 

            return newCollection.AsReadOnlyMetadataCollection(); 
        }

        /// 
        /// Get the number of members the base type has.  If the base type is not a structural type or has no 
        /// members, it returns 0
        ///  
        /// The number of members in the base type 
        private int GetBaseTypeMemberCount()
        { 
            // The count of members is what in this collection plus base type's member collection
            StructuralType baseType = _declaringType.BaseType as StructuralType;
            if (baseType != null)
            { 
                return baseType.Members.Count;
            } 
 
            return 0;
        } 

        /// 
        /// Gets the index relative to this collection for the given index.  For an index to really refers to something in
        /// the base type, the return value is negative relative to this collection.  For an index refers to something in this 
        /// collection, the return value is positive.  In both cases, it's simply (index) - (base type member count)
        ///  
        /// The relative index 
        private int GetRelativeIndex(int index)
        { 
            int baseTypeMemberCount = GetBaseTypeMemberCount();
            int thisTypeMemberCount = base.Count;

            // Check if the index is in range 
            if (index < 0 || index >= baseTypeMemberCount + thisTypeMemberCount)
            { 
                throw EntityUtil.ArgumentOutOfRange("index"); 
            }
 
            return index - baseTypeMemberCount;
        }

        ///  
        /// Checks if the given member already has a declaring type, if so, throw an exception
        ///  
        /// The member to check for 
        /// The name of the argument from the caller
        private static void ThrowIfItHasDeclaringType(EdmMember member, string argumentName) 
        {
            EntityUtil.GenericCheckArgumentNull(member, argumentName);
            if (member.DeclaringType != null)
            { 
                throw EntityUtil.MemberAlreadyBelongsToType(argumentName);
            } 
        } 

        private void ValidateMemberForAdd(EdmMember member, string argumentName) 
        {
            // Check to make sure the given member is not associated with another type
            ThrowIfItHasDeclaringType(member, argumentName);
 
            // Validate the item with the declaring type.
            _declaringType.ValidateMemberForAdd(member); 
        } 

        #endregion 
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK