CollectionDataContract.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / CollectionDataContract.cs / 3 / CollectionDataContract.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Runtime.Serialization
{ 
    using System;
    using System.Collections; 
    using System.Diagnostics; 
    using System.Collections.Generic;
    using System.IO; 
    using System.Globalization;
    using System.Reflection;
    using System.Threading;
    using System.Xml; 
    using System.Runtime.Serialization.Configuration;
    using DataContractDictionary=System.Collections.Generic.Dictionary; 
    using System.Security; 
    using System.Security.Permissions;
 
    [DataContract(Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")]
#if USE_REFEMIT
    public struct KeyValue
#else 
    internal struct KeyValue
#endif 
    { 
        K key;
        V value; 

        internal KeyValue(K key, V value)
        {
            this.key = key; 
            this.value = value;
        } 
 
        [DataMember(IsRequired = true)]
        public K Key 
        {
            get { return key; }
            set { key = value; }
        } 

        [DataMember(IsRequired = true)] 
        public V Value 
        {
            get { return value; } 
            set { this.value = value; }
        }
    }
 
    internal enum CollectionKind : byte
    { 
        None, 
        GenericDictionary,
        Dictionary, 
        GenericList,
        GenericCollection,
        List,
        GenericEnumerable, 
        Collection,
        Enumerable, 
        Array, 
    }
 
#if USE_REFEMIT
    public sealed class CollectionDataContract : DataContract
#else
    internal sealed class CollectionDataContract : DataContract 
#endif
    { 
        ///  
        /// Critical - XmlDictionaryString representing the XML element name for collection items.
        ///            statically cached and used from IL generated code. 
        /// 
        [SecurityCritical]
        XmlDictionaryString collectionItemName;
        ///  
        /// Critical - XmlDictionaryString representing the XML namespace for collection items.
        ///            statically cached and used from IL generated code. 
        ///  
        [SecurityCritical]
        XmlDictionaryString childElementNamespace; 
        /// 
        /// Critical - internal DataContract representing the contract for collection items.
        ///            statically cached and used from IL generated code.
        ///  
        [SecurityCritical]
        DataContract itemContract; 
 
        /// 
        /// Critical - holds instance of CriticalHelper which keeps state that is cached statically for serialization. 
        ///            Static fields are marked SecurityCritical or readonly to prevent
        ///            data from being modified or leaked to other components in appdomain.
        /// 
        [SecurityCritical] 
        CollectionDataContractCriticalHelper helper;
 
        ///  
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal CollectionDataContract(CollectionKind kind) : base(new CollectionDataContractCriticalHelper(kind))
        { 
            InitCollectionDataContract(this);
        } 
 
        /// 
        /// Critical - initializes SecurityCritical field 'helper' 
        /// Safe - doesn't leak anything
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal CollectionDataContract(Type type) : base(new CollectionDataContractCriticalHelper(type)) 
        {
            InitCollectionDataContract(this); 
        } 

        ///  
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal CollectionDataContract(Type type, DataContract itemContract) : base(new CollectionDataContractCriticalHelper(type, itemContract))
        { 
            InitCollectionDataContract(this); 
        }
 
        /// 
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        CollectionDataContract(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor) 
            : base(new CollectionDataContractCriticalHelper(type, kind, itemType, getEnumeratorMethod, addMethod, constructor)) 
        {
            InitCollectionDataContract(GetSharedTypeContract(type)); 
        }

        /// 
        /// Critical - initializes SecurityCritical field 'helper' 
        /// Safe - doesn't leak anything
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        CollectionDataContract(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor, bool isConstructorCheckRequired)
            : base(new CollectionDataContractCriticalHelper(type, kind, itemType, getEnumeratorMethod, addMethod, constructor, isConstructorCheckRequired)) 
        {
            InitCollectionDataContract(GetSharedTypeContract(type));
        }
 
        /// 
        /// Critical - initializes SecurityCritical field 'helper' 
        /// Safe - doesn't leak anything 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        CollectionDataContract(Type type, string invalidCollectionInSharedContractMessage) : base(new CollectionDataContractCriticalHelper(type, invalidCollectionInSharedContractMessage))
        {
            InitCollectionDataContract(GetSharedTypeContract(type));
        } 

        ///  
        /// Critical - initializes SecurityCritical fields; called from all constructors 
        /// 
        [SecurityCritical] 
        void InitCollectionDataContract(DataContract sharedTypeContract)
        {
            this.helper = base.Helper as CollectionDataContractCriticalHelper;
            this.collectionItemName = helper.CollectionItemName; 
            if (helper.Kind == CollectionKind.Dictionary || helper.Kind == CollectionKind.GenericDictionary)
            { 
                this.itemContract = helper.ItemContract; 
            }
            this.helper.SharedTypeContract = sharedTypeContract; 
        }

        void InitSharedTypeContract()
        { 
        }
 
        static Type[] KnownInterfaces 
        {
            ///  
            /// Critical - fetches the critical knownInterfaces property
            /// Safe - knownInterfaces only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return CollectionDataContractCriticalHelper.KnownInterfaces; }
        } 
 
        internal CollectionKind Kind
        { 
            /// 
            /// Critical - fetches the critical kind property
            /// Safe - kind only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.Kind; } 
        } 

        internal Type ItemType 
        {
            /// 
            /// Critical - fetches the critical itemType property
            /// Safe - itemType only needs to be protected for write 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.ItemType; } 
        }
 
        public DataContract ItemContract
        {
            /// 
            /// Critical - fetches the critical itemContract property 
            /// Safe - itemContract only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return itemContract ?? helper.ItemContract; }
            ///  
            /// Critical - sets the critical itemContract property
            /// 
            [SecurityCritical]
            set 
            {
                itemContract = value; 
                helper.ItemContract = value; 
            }
        } 

        internal DataContract SharedTypeContract
        {
            ///  
            /// Critical - fetches the critical sharedTypeContract property
            /// Safe - sharedTypeContract only needs to be protected for write 
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.SharedTypeContract; } 
        }

        internal string ItemName
        { 
            /// 
            /// Critical - fetches the critical itemName property 
            /// Safe - itemName only needs to be protected for write 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.ItemName; }
            /// 
            /// Critical - sets the critical itemName property
            ///  
            [SecurityCritical]
            set { helper.ItemName = value; } 
        } 

        public XmlDictionaryString CollectionItemName 
        {
            /// 
            /// Critical - fetches the critical collectionItemName property
            /// Safe - collectionItemName only needs to be protected for write 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return this.collectionItemName; } 
        }
 
        internal string KeyName
        {
            /// 
            /// Critical - fetches the critical keyName property 
            /// Safe - keyName only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.KeyName; }
            ///  
            /// Critical - sets the critical keyName property
            /// 
            [SecurityCritical]
            set { helper.KeyName = value; } 
        }
 
        internal string ValueName 
        {
            ///  
            /// Critical - fetches the critical valueName property
            /// Safe - valueName only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.ValueName; }
            ///  
            /// Critical - sets the critical valueName property 
            /// 
            [SecurityCritical] 
            set {  helper.ValueName = value; }
        }

        internal bool IsDictionary 
        {
            get { return KeyName != null; } 
        } 

        public XmlDictionaryString ChildElementNamespace 
        {
            /// 
            /// Critical - fetches the critical childElementNamespace property
            /// Safe - childElementNamespace only needs to be protected for write; initialized in getter if null 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get 
            {
                if (this.childElementNamespace == null) 
                {
                    lock (this)
                    {
                        if (this.childElementNamespace == null) 
                        {
                            if (helper.ChildElementNamespace == null && !IsDictionary) 
                            { 
                                XmlDictionaryString tempChildElementNamespace = ClassDataContract.GetChildNamespaceToDeclare(this, ItemType, new XmlDictionary());
                                Thread.MemoryBarrier(); 
                                helper.ChildElementNamespace = tempChildElementNamespace;
                            }
                            this.childElementNamespace = helper.ChildElementNamespace;
                        } 
                    }
                } 
                return childElementNamespace; 
            }
        } 

        internal bool IsItemTypeNullable
        {
            ///  
            /// Critical - fetches the critical isItemTypeNullable property
            /// Safe - isItemTypeNullable only needs to be protected for write 
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.IsItemTypeNullable; } 
            /// 
            /// Critical - sets the critical isItemTypeNullable property
            /// 
            [SecurityCritical] 
            set { helper.IsItemTypeNullable = value; }
        } 
 
        internal bool IsConstructorCheckRequired
        { 
            /// 
            /// Critical - fetches the critical isConstructorCheckRequired property
            /// Safe - isConstructorCheckRequired only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.IsConstructorCheckRequired; } 
            ///  
            /// Critical - sets the critical isConstructorCheckRequired property
            ///  
            [SecurityCritical]
            set { helper.IsConstructorCheckRequired = value; }
        }
 
        internal MethodInfo GetEnumeratorMethod
        { 
            ///  
            /// Critical - fetches the critical getEnumeratorMethod property
            /// Safe - getEnumeratorMethod only needs to be protected for write 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.GetEnumeratorMethod; }
        } 

        internal MethodInfo AddMethod 
        { 
            /// 
            /// Critical - fetches the critical addMethod property 
            /// Safe - addMethod only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.AddMethod; } 
        }
 
        internal ConstructorInfo Constructor 
        {
            ///  
            /// Critical - fetches the critical constructor property
            /// Safe - constructor only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.Constructor; }
        } 
 
        internal override DataContractDictionary KnownDataContracts
        { 
            /// 
            /// Critical - fetches the critical knownDataContracts property
            /// Safe - knownDataContracts only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.KnownDataContracts; } 
            ///  
            /// Critical - sets the critical knownDataContracts property
            ///  
            [SecurityCritical]
            set { helper.KnownDataContracts = value; }
        }
 
        internal string InvalidCollectionInSharedContractMessage
        { 
            ///  
            /// Critical - fetches the critical invalidCollectionInSharedContractMessage property
            /// Safe - invalidCollectionInSharedContractMessage only needs to be protected for write 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.InvalidCollectionInSharedContractMessage; }
        } 

        bool ItemNameSetExplicit 
        { 
            /// 
            /// Critical - fetches the critical itemNameSetExplicit property 
            /// Safe - itemNameSetExplicit only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.ItemNameSetExplicit; } 
        }
 
        internal XmlFormatCollectionWriterDelegate XmlFormatWriterDelegate 
        {
            ///  
            /// Critical - fetches the critical xmlFormatWriterDelegate property
            /// Safe - xmlFormatWriterDelegate only needs to be protected for write; initialized in getter if null
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            { 
                if (helper.XmlFormatWriterDelegate == null) 
                {
                    lock (this) 
                    {
                        if (helper.XmlFormatWriterDelegate == null)
                        {
                            XmlFormatCollectionWriterDelegate tempDelegate = new XmlFormatWriterGenerator().GenerateCollectionWriter(this); 
                            Thread.MemoryBarrier();
                            helper.XmlFormatWriterDelegate = tempDelegate; 
                        } 
                    }
                } 
                return helper.XmlFormatWriterDelegate;
            }
        }
 
        internal XmlFormatCollectionReaderDelegate XmlFormatReaderDelegate
        { 
            ///  
            /// Critical - fetches the critical xmlFormatReaderDelegate property
            /// Safe - xmlFormatReaderDelegate only needs to be protected for write; initialized in getter if null 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get
            { 
                if (helper.XmlFormatReaderDelegate == null)
                { 
                    lock (this) 
                    {
                        if (helper.XmlFormatReaderDelegate == null) 
                        {
                            XmlFormatCollectionReaderDelegate tempDelegate = new XmlFormatReaderGenerator().GenerateCollectionReader(this);
                            Thread.MemoryBarrier();
                            helper.XmlFormatReaderDelegate = tempDelegate; 
                        }
                    } 
                } 
                return helper.XmlFormatReaderDelegate;
            } 
        }

        internal XmlFormatGetOnlyCollectionReaderDelegate XmlFormatGetOnlyCollectionReaderDelegate
        { 
            /// 
            /// Critical - fetches the critical xmlFormatReaderDelegate property 
            /// Safe - xmlFormatReaderDelegate only needs to be protected for write; initialized in getter if null 
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get
            {
                if (helper.XmlFormatGetOnlyCollectionReaderDelegate == null)
                { 
                    lock (this)
                    { 
                        if (helper.XmlFormatGetOnlyCollectionReaderDelegate == null) 
                        {
                            XmlFormatGetOnlyCollectionReaderDelegate tempDelegate = new XmlFormatReaderGenerator().GenerateGetOnlyCollectionReader(this); 
                            Thread.MemoryBarrier();
                            helper.XmlFormatGetOnlyCollectionReaderDelegate = tempDelegate;
                        }
                    } 
                }
                return helper.XmlFormatGetOnlyCollectionReaderDelegate; 
            } 
        }
 
        /// 
        /// Critical - holds all state used for (de)serializing collections.
        ///            since the data is cached statically, we lock down access to it.
        ///  
        [SecurityCritical(SecurityCriticalScope.Everything)]
        class CollectionDataContractCriticalHelper : DataContract.DataContractCriticalHelper 
        { 
            static Type[] _knownInterfaces;
 
            Type itemType;
            bool isItemTypeNullable;
            CollectionKind kind;
            readonly MethodInfo getEnumeratorMethod, addMethod; 
            readonly ConstructorInfo constructor;
            DataContract itemContract; 
            DataContract sharedTypeContract; 
            DataContractDictionary knownDataContracts;
            bool isKnownTypeAttributeChecked; 
            string itemName;
            bool itemNameSetExplicit;
            XmlDictionaryString collectionItemName;
            string keyName; 
            string valueName;
            XmlDictionaryString childElementNamespace; 
            string invalidCollectionInSharedContractMessage; 
            XmlFormatCollectionReaderDelegate xmlFormatReaderDelegate;
            XmlFormatGetOnlyCollectionReaderDelegate xmlFormatGetOnlyCollectionReaderDelegate; 
            XmlFormatCollectionWriterDelegate xmlFormatWriterDelegate;
            bool isConstructorCheckRequired = false;

            internal static Type[] KnownInterfaces 
            {
                get 
                { 
                    if (_knownInterfaces == null)
                    { 
                        // Listed in priority order
                        _knownInterfaces = new Type[]
                    {
                        Globals.TypeOfIDictionaryGeneric, 
                        Globals.TypeOfIDictionary,
                        Globals.TypeOfIListGeneric, 
                        Globals.TypeOfICollectionGeneric, 
                        Globals.TypeOfIList,
                        Globals.TypeOfIEnumerableGeneric, 
                        Globals.TypeOfICollection,
                        Globals.TypeOfIEnumerable
                    };
                    } 
                    return _knownInterfaces;
                } 
            } 

            void Init(CollectionKind kind, Type itemType, CollectionDataContractAttribute collectionContractAttribute) 
            {
                this.kind = kind;
                if (itemType != null)
                { 
                    this.itemType = itemType;
                    this.isItemTypeNullable = DataContract.IsTypeNullable(itemType); 
 
                    bool isDictionary = (kind == CollectionKind.Dictionary || kind == CollectionKind.GenericDictionary);
                    string itemName = null, keyName = null, valueName = null; 
                    if (collectionContractAttribute != null)
                    {
                        if (collectionContractAttribute.IsItemNameSetExplicit)
                        { 
                            if (collectionContractAttribute.ItemName == null || collectionContractAttribute.ItemName.Length == 0)
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractItemName, DataContract.GetClrTypeFullName(UnderlyingType)))); 
                            itemName = DataContract.EncodeLocalName(collectionContractAttribute.ItemName); 
                            itemNameSetExplicit = true;
                        } 
                        if (collectionContractAttribute.IsKeyNameSetExplicit)
                        {
                            if (collectionContractAttribute.KeyName == null || collectionContractAttribute.KeyName.Length == 0)
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractKeyName, DataContract.GetClrTypeFullName(UnderlyingType)))); 
                            if (!isDictionary)
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractKeyNoDictionary, DataContract.GetClrTypeFullName(UnderlyingType), collectionContractAttribute.KeyName))); 
                            keyName = DataContract.EncodeLocalName(collectionContractAttribute.KeyName); 
                        }
                        if (collectionContractAttribute.IsValueNameSetExplicit) 
                        {
                            if (collectionContractAttribute.ValueName == null || collectionContractAttribute.ValueName.Length == 0)
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractValueName, DataContract.GetClrTypeFullName(UnderlyingType))));
                            if (!isDictionary) 
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractValueNoDictionary, DataContract.GetClrTypeFullName(UnderlyingType), collectionContractAttribute.ValueName)));
                            valueName = DataContract.EncodeLocalName(collectionContractAttribute.ValueName); 
                        } 
                    }
 
                    XmlDictionary dictionary = isDictionary ? new XmlDictionary(5) : new XmlDictionary(3);
                    this.Name = dictionary.Add(this.StableName.Name);
                    this.Namespace = dictionary.Add(this.StableName.Namespace);
                    this.itemName = itemName ?? DataContract.GetStableName(DataContract.UnwrapNullableType(itemType)).Name; 
                    this.collectionItemName = dictionary.Add(this.itemName);
                    if (isDictionary) 
                    { 
                        this.keyName = keyName ?? Globals.KeyLocalName;
                        this.valueName = valueName ?? Globals.ValueLocalName; 
                    }
                }
                if (collectionContractAttribute != null)
                { 
                    this.IsReference = collectionContractAttribute.IsReference;
                } 
            } 

            internal CollectionDataContractCriticalHelper(CollectionKind kind) : base() 
            {
                Init(kind, null, null);
            }
 
            // array
            internal CollectionDataContractCriticalHelper(Type type) : base(type) 
            { 
                if (type == Globals.TypeOfArray)
                    type = Globals.TypeOfObjectArray; 
                if (type.GetArrayRank() > 1)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SupportForMultidimensionalArraysNotPresent)));
                this.StableName = DataContract.GetStableName(type);
                Init(CollectionKind.Array, type.GetElementType(), null); 
            }
 
            // array 
            internal CollectionDataContractCriticalHelper(Type type, DataContract itemContract) : base(type)
            { 
                if (type.GetArrayRank() > 1)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SupportForMultidimensionalArraysNotPresent)));
                this.StableName = CreateQualifiedName(Globals.ArrayPrefix + itemContract.StableName.Name, itemContract.StableName.Namespace);
                this.itemContract = itemContract; 
                Init(CollectionKind.Array, type.GetElementType(), null);
            } 
 
            // collection
            internal CollectionDataContractCriticalHelper(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor) : base(type) 
            {
                if (getEnumeratorMethod == null)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CollectionMustHaveGetEnumeratorMethod, DataContract.GetClrTypeFullName(type))));
                if (addMethod == null && !type.IsInterface) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CollectionMustHaveAddMethod, DataContract.GetClrTypeFullName(type))));
                if (itemType == null) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CollectionMustHaveItemType, DataContract.GetClrTypeFullName(type)))); 

                CollectionDataContractAttribute collectionContractAttribute; 
                this.StableName = DataContract.GetCollectionStableName(type, itemType, out collectionContractAttribute);

                Init(kind, itemType, collectionContractAttribute);
                this.getEnumeratorMethod = getEnumeratorMethod; 
                this.addMethod = addMethod;
                this.constructor = constructor; 
            } 

            // collection 
            internal CollectionDataContractCriticalHelper(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor, bool isConstructorCheckRequired)
                : this(type, kind, itemType, getEnumeratorMethod, addMethod, constructor)
            {
                this.isConstructorCheckRequired = isConstructorCheckRequired; 
            }
 
            internal CollectionDataContractCriticalHelper(Type type, string invalidCollectionInSharedContractMessage) : base(type) 
            {
                Init(CollectionKind.Collection, null /*itemType*/, null); 
                this.invalidCollectionInSharedContractMessage = invalidCollectionInSharedContractMessage;
            }

            internal CollectionKind Kind 
            {
                get { return kind; } 
            } 

            internal Type ItemType 
            {
                get { return itemType; }
            }
 
            internal DataContract ItemContract
            { 
                get 
                {
                    if (itemContract == null && UnderlyingType != null) 
                    {
                        if (IsDictionary)
                        {
                            if (String.CompareOrdinal(KeyName, ValueName) == 0) 
                            {
                                DataContract.ThrowInvalidDataContractException( 
                                    SR.GetString(SR.DupKeyValueName, DataContract.GetClrTypeFullName(UnderlyingType), KeyName), 
                                    UnderlyingType);
                            } 
                            itemContract = ClassDataContract.CreateClassDataContractForKeyValue(ItemType, Namespace, new string[] { KeyName, ValueName });
                            // Ensure that DataContract gets added to the static DataContract cache for dictionary items
                            DataContract.GetDataContract(ItemType);
                        } 
                        else
                        { 
                            itemContract = DataContract.GetDataContract(ItemType); 
                        }
                    } 
                    return itemContract;
                }
                set
                { 
                    itemContract = value;
                } 
            } 

            internal DataContract SharedTypeContract 
            {
                get { return sharedTypeContract; }
                set { sharedTypeContract = value; }
            } 

            internal string ItemName 
            { 
                get { return itemName; }
                set { itemName = value; } 
            }

            internal bool IsConstructorCheckRequired
            { 
                get { return isConstructorCheckRequired; }
                set { isConstructorCheckRequired = value; } 
            } 

            public XmlDictionaryString CollectionItemName 
            {
                get { return collectionItemName; }
            }
 
            internal string KeyName
            { 
                get { return keyName; } 
                set { keyName = value; }
            } 

            internal string ValueName
            {
                get { return valueName; } 
                set { valueName = value; }
            } 
 
            internal bool IsDictionary
            { 
                get { return KeyName != null; }
            }

            public XmlDictionaryString ChildElementNamespace 
            {
                get { return childElementNamespace; } 
                set { childElementNamespace = value; } 
            }
 
            internal bool IsItemTypeNullable
            {
                get { return isItemTypeNullable; }
                set { isItemTypeNullable = value; } 
            }
 
            internal MethodInfo GetEnumeratorMethod 
            {
                get { return getEnumeratorMethod; } 
            }

            internal MethodInfo AddMethod
            { 
                get { return addMethod; }
            } 
 
            internal ConstructorInfo Constructor
            { 
                get { return constructor; }
            }

            internal override DataContractDictionary KnownDataContracts 
            {
                get 
                { 
                    if (!isKnownTypeAttributeChecked && UnderlyingType != null)
                    { 
                        lock (this)
                        {
                            if (!isKnownTypeAttributeChecked)
                            { 
                                knownDataContracts = DataContract.ImportKnownTypeAttributes(this.UnderlyingType);
                                Thread.MemoryBarrier(); 
                                isKnownTypeAttributeChecked = true; 
                            }
                        } 
                    }
                    return knownDataContracts;
                }
                set { knownDataContracts = value; } 
            }
 
            internal string InvalidCollectionInSharedContractMessage 
            {
                get { return invalidCollectionInSharedContractMessage; } 
            }

            internal bool ItemNameSetExplicit
            { 
                get { return itemNameSetExplicit; }
            } 
 
            internal XmlFormatCollectionWriterDelegate XmlFormatWriterDelegate
            { 
                get { return xmlFormatWriterDelegate; }
                set { xmlFormatWriterDelegate = value; }
            }
 
            internal XmlFormatCollectionReaderDelegate XmlFormatReaderDelegate
            { 
                get { return xmlFormatReaderDelegate; } 
                set { xmlFormatReaderDelegate = value; }
            } 

            internal XmlFormatGetOnlyCollectionReaderDelegate XmlFormatGetOnlyCollectionReaderDelegate
            {
                get { return xmlFormatGetOnlyCollectionReaderDelegate; } 
                set { xmlFormatGetOnlyCollectionReaderDelegate = value; }
            } 
        } 

        DataContract GetSharedTypeContract(Type type) 
        {
            if (type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false))
            {
                return this; 
            }
            // ClassDataContract.IsSerializableTypeValidForSerialization does not need to be called here. It should 
            // never pass because it returns false for types that implement any of CollectionDataContract.KnownInterfaces 
            if (type.IsSerializable || type.IsDefined(Globals.TypeOfDataContractAttribute, false))
            { 
                return new ClassDataContract(type);
            }
            return null;
        } 

        internal static bool IsCollectionInterface(Type type) 
        { 
            if (type.IsGenericType)
                type = type.GetGenericTypeDefinition(); 
            return ((IList)KnownInterfaces).Contains(type);
        }

        internal static bool IsCollection(Type type) 
        {
            Type itemType; 
            return IsCollection(type, out itemType); 
        }
 
        internal static bool IsCollection(Type type, out Type itemType)
        {
            return IsCollectionHelper(type, out itemType, true /*constructorRequired*/);
        } 

        internal static bool IsCollection(Type type, bool constructorRequired) 
        { 
            Type itemType;
            return IsCollectionHelper(type, out itemType, constructorRequired); 
        }

        static bool IsCollectionHelper(Type type, out Type itemType, bool constructorRequired)
        { 
            if (type.IsArray && DataContract.GetBuiltInDataContract(type) == null)
            { 
                itemType = type.GetElementType(); 
                return true;
            } 
            DataContract dataContract;
            return IsCollectionOrTryCreate(type, false /*tryCreate*/, out dataContract, out itemType, constructorRequired);
        }
 
        internal static bool TryCreate(Type type, out DataContract dataContract)
        { 
            Type itemType; 
            return IsCollectionOrTryCreate(type, true /*tryCreate*/, out dataContract, out itemType, true /*constructorRequired*/);
        } 

        internal static bool CreateGetOnlyCollectionDataContract(Type type, out DataContract dataContract)
        {
            Type itemType; 
            if (type.IsArray)
            { 
                dataContract = new CollectionDataContract(type); 
                return true;
            } 
            else
            {
                return IsCollectionOrTryCreate(type, true /*tryCreate*/, out dataContract, out itemType, false /*constructorRequired*/);
            } 
        }
 
        internal static MethodInfo GetTargetMethodWithName(string name, Type type, Type interfaceType) 
        {
            InterfaceMapping mapping = type.GetInterfaceMap(interfaceType); 
            for (int i = 0; i < mapping.TargetMethods.Length; i++)
            {
                if (mapping.InterfaceMethods[i].Name == name)
                    return mapping.InterfaceMethods[i]; 
            }
            return null; 
        } 

        static bool IsCollectionOrTryCreate(Type type, bool tryCreate, out DataContract dataContract, out Type itemType, bool constructorRequired) 
        {
            dataContract = null;
            itemType = Globals.TypeOfObject;
 
            if (DataContract.GetBuiltInDataContract(type) != null)
            { 
                return HandleIfInvalidCollection(type, tryCreate, false/*hasCollectionDataContract*/, false/*isBaseTypeCollection*/, 
                    SR.CollectionTypeCannotBeBuiltIn, null, ref dataContract);
            } 
            MethodInfo addMethod, getEnumeratorMethod;
            bool hasCollectionDataContract = IsCollectionDataContract(type);
            Type baseType = type.BaseType;
            bool isBaseTypeCollection = (baseType != null && baseType != Globals.TypeOfObject 
                && baseType != Globals.TypeOfValueType && baseType != Globals.TypeOfUri) ? IsCollection(baseType) : false;
 
            if (type.IsDefined(Globals.TypeOfDataContractAttribute, false)) 
            {
                return HandleIfInvalidCollection(type, tryCreate, hasCollectionDataContract, isBaseTypeCollection, 
                    SR.CollectionTypeCannotHaveDataContract, null, ref dataContract);
            }

            if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(type)) 
            {
                return false; 
            } 

            if (!Globals.TypeOfIEnumerable.IsAssignableFrom(type)) 
            {
                return HandleIfInvalidCollection(type, tryCreate, hasCollectionDataContract, isBaseTypeCollection,
                    SR.CollectionTypeIsNotIEnumerable, null, ref dataContract);
            } 
            if (type.IsInterface)
            { 
                Type interfaceTypeToCheck = type.IsGenericType ? type.GetGenericTypeDefinition() : type; 
                Type[] knownInterfaces = KnownInterfaces;
                for (int i = 0; i < knownInterfaces.Length; i++) 
                {
                    if (knownInterfaces[i] == interfaceTypeToCheck)
                    {
                        addMethod = null; 
                        if (type.IsGenericType)
                        { 
                            Type[] genericArgs = type.GetGenericArguments(); 
                            if (interfaceTypeToCheck == Globals.TypeOfIDictionaryGeneric)
                            { 
                                itemType = Globals.TypeOfKeyValue.MakeGenericType(genericArgs);
                                addMethod = type.GetMethod(Globals.AddMethodName);
                                getEnumeratorMethod = Globals.TypeOfIEnumerableGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(genericArgs)).GetMethod(Globals.GetEnumeratorMethodName);
                            } 
                            else
                            { 
                                itemType = genericArgs[0]; 
                                getEnumeratorMethod = Globals.TypeOfIEnumerableGeneric.MakeGenericType(itemType).GetMethod(Globals.GetEnumeratorMethodName);
                            } 
                        }
                        else
                        {
                            if (interfaceTypeToCheck == Globals.TypeOfIDictionary) 
                            {
                                itemType = typeof(KeyValue); 
                                addMethod = type.GetMethod(Globals.AddMethodName); 
                            }
                            else 
                            {
                                itemType = Globals.TypeOfObject;
                            }
                            getEnumeratorMethod = Globals.TypeOfIEnumerable.GetMethod(Globals.GetEnumeratorMethodName); 
                        }
                        if (tryCreate) 
                            dataContract = new CollectionDataContract(type, (CollectionKind)(i + 1), itemType, getEnumeratorMethod, addMethod, null/*defaultCtor*/); 
                        return true;
                    } 
                }
            }
            ConstructorInfo defaultCtor = null;
            if (!type.IsValueType) 
            {
                defaultCtor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Globals.EmptyTypeArray, null); 
                if (defaultCtor == null && constructorRequired) 
                {
                    return HandleIfInvalidCollection(type, tryCreate, hasCollectionDataContract, isBaseTypeCollection/*createContractWithException*/, 
                        SR.CollectionTypeDoesNotHaveDefaultCtor, null, ref dataContract);
                }
            }
 
            Type knownInterfaceType = null;
            CollectionKind kind = CollectionKind.None; 
            bool multipleDefinitions = false; 
            Type[] interfaceTypes = type.GetInterfaces();
            foreach (Type interfaceType in interfaceTypes) 
            {
                Type interfaceTypeToCheck = interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType;
                Type[] knownInterfaces = KnownInterfaces;
                for (int i = 0; i < knownInterfaces.Length; i++) 
                {
                    if (knownInterfaces[i] == interfaceTypeToCheck) 
                    { 
                        CollectionKind currentKind = (CollectionKind)(i + 1);
                        if (kind == CollectionKind.None || currentKind < kind) 
                        {
                            kind = currentKind;
                            knownInterfaceType = interfaceType;
                            multipleDefinitions = false; 
                        }
                        else if ((kind & currentKind) == currentKind) 
                            multipleDefinitions = true; 
                        break;
                    } 
                }
            }

            if (kind == CollectionKind.None) 
            {
                return HandleIfInvalidCollection(type, tryCreate, hasCollectionDataContract, isBaseTypeCollection, 
                    SR.CollectionTypeIsNotIEnumerable, null, ref dataContract); 
            }
 
            if (kind == CollectionKind.Enumerable || kind == CollectionKind.Collection || kind == CollectionKind.GenericEnumerable)
            {
                if (multipleDefinitions)
                    knownInterfaceType = Globals.TypeOfIEnumerable; 
                itemType = knownInterfaceType.IsGenericType ? knownInterfaceType.GetGenericArguments()[0] : Globals.TypeOfObject;
                GetCollectionMethods(type, knownInterfaceType, new Type[] { itemType }, 
                                     false /*addMethodOnInterface*/, 
                                     out getEnumeratorMethod, out addMethod);
                if (addMethod == null) 
                {
                    return HandleIfInvalidCollection(type, tryCreate, hasCollectionDataContract, isBaseTypeCollection/*createContractWithException*/,
                        SR.CollectionTypeDoesNotHaveAddMethod, DataContract.GetClrTypeFullName(itemType), ref dataContract);
                } 
                if (tryCreate)
                    dataContract = new CollectionDataContract(type, kind, itemType, getEnumeratorMethod, addMethod, defaultCtor, !constructorRequired); 
            } 
            else
            { 
                if (multipleDefinitions)
                {
                    return HandleIfInvalidCollection(type, tryCreate, hasCollectionDataContract, isBaseTypeCollection/*createContractWithException*/,
                        SR.CollectionTypeHasMultipleDefinitionsOfInterface, KnownInterfaces[(int)kind - 1].Name, ref dataContract); 
                }
                Type[] addMethodTypeArray = null; 
                switch (kind) 
                {
                    case CollectionKind.GenericDictionary: 
                        addMethodTypeArray = knownInterfaceType.GetGenericArguments();
                        bool isOpenGeneric = knownInterfaceType.IsGenericTypeDefinition
                            || (addMethodTypeArray[0].IsGenericParameter && addMethodTypeArray[1].IsGenericParameter);
                        itemType = isOpenGeneric ? Globals.TypeOfKeyValue : Globals.TypeOfKeyValue.MakeGenericType(addMethodTypeArray); 
                        break;
                    case CollectionKind.Dictionary: 
                        addMethodTypeArray = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject }; 
                        itemType = Globals.TypeOfKeyValue.MakeGenericType(addMethodTypeArray);
                        break; 
                    case CollectionKind.GenericList:
                    case CollectionKind.GenericCollection:
                        addMethodTypeArray = knownInterfaceType.GetGenericArguments();
                        itemType = addMethodTypeArray[0]; 
                        break;
                    case CollectionKind.List: 
                        itemType = Globals.TypeOfObject; 
                        addMethodTypeArray = new Type[] { itemType };
                        break; 
                }

                if (tryCreate)
                { 
                    GetCollectionMethods(type, knownInterfaceType, addMethodTypeArray,
                                     true /*addMethodOnInterface*/, 
                                     out getEnumeratorMethod, out addMethod); 
                    dataContract = new CollectionDataContract(type, kind, itemType, getEnumeratorMethod, addMethod, defaultCtor, !constructorRequired);
                } 
            }

            return true;
        } 

        internal static bool IsCollectionDataContract(Type type) 
        { 
            return type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false);
        } 

        static bool HandleIfInvalidCollection(Type type, bool tryCreate, bool hasCollectionDataContract, bool createContractWithException, string message, string param, ref DataContract dataContract)
        {
            if (hasCollectionDataContract) 
            {
                if (tryCreate) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(GetInvalidCollectionMessage(message, SR.GetString(SR.InvalidCollectionDataContract, DataContract.GetClrTypeFullName(type)), param))); 
                return true;
            } 

            if (createContractWithException)
            {
                if (tryCreate) 
                    dataContract = new CollectionDataContract(type, GetInvalidCollectionMessage(message, SR.GetString(SR.InvalidCollectionType, DataContract.GetClrTypeFullName(type)), param));
                return true; 
            } 

            return false; 
        }

        static string GetInvalidCollectionMessage(string message, string nestedMessage, string param)
        { 
            return (param == null) ? SR.GetString(message, nestedMessage) : SR.GetString(message, nestedMessage, param);
        } 
 
        static void FindCollectionMethodsOnInterface(Type type, Type interfaceType, ref MethodInfo addMethod, ref MethodInfo getEnumeratorMethod)
        { 
            InterfaceMapping mapping = type.GetInterfaceMap(interfaceType);
            for (int i = 0; i < mapping.TargetMethods.Length; i++)
            {
                if (mapping.InterfaceMethods[i].Name == Globals.AddMethodName) 
                    addMethod = mapping.InterfaceMethods[i];
                else if (mapping.InterfaceMethods[i].Name == Globals.GetEnumeratorMethodName) 
                    getEnumeratorMethod = mapping.InterfaceMethods[i]; 
            }
        } 

        static void GetCollectionMethods(Type type, Type interfaceType, Type[] addMethodTypeArray, bool addMethodOnInterface, out MethodInfo getEnumeratorMethod, out MethodInfo addMethod)
        {
            addMethod = getEnumeratorMethod = null; 

            if (addMethodOnInterface) 
            { 
                addMethod = type.GetMethod(Globals.AddMethodName, BindingFlags.Instance | BindingFlags.Public, null, addMethodTypeArray, null);
                if (addMethod == null || addMethod.GetParameters()[0].ParameterType != addMethodTypeArray[0]) 
                {
                    FindCollectionMethodsOnInterface(type, interfaceType, ref addMethod, ref getEnumeratorMethod);
                    if (addMethod == null)
                    { 
                        Type[] parentInterfaceTypes = interfaceType.GetInterfaces();
                        foreach (Type parentInterfaceType in parentInterfaceTypes) 
                        { 
                            if (IsKnownInterface(parentInterfaceType))
                            { 
                                FindCollectionMethodsOnInterface(type, parentInterfaceType, ref addMethod, ref getEnumeratorMethod);
                                if (addMethod == null)
                                {
                                    break; 
                                }
                            } 
                        } 
                    }
                } 
            }
            else
            {
                // GetMethod returns Add() method with parameter closest matching T in assignability/inheritance chain 
                addMethod = type.GetMethod(Globals.AddMethodName, BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic, null, addMethodTypeArray, null);
                if (addMethod == null) 
                    return; 
            }
 
            if (getEnumeratorMethod == null)
            {
                getEnumeratorMethod = type.GetMethod(Globals.GetEnumeratorMethodName, BindingFlags.Instance|BindingFlags.Public, null, Globals.EmptyTypeArray, null);
                if (getEnumeratorMethod == null || !Globals.TypeOfIEnumerator.IsAssignableFrom(getEnumeratorMethod.ReturnType)) 
                {
                    Type ienumerableInterface = interfaceType.GetInterface("System.Collections.Generic.IEnumerable*"); 
                    if (ienumerableInterface == null) 
                        ienumerableInterface = Globals.TypeOfIEnumerable;
                    getEnumeratorMethod = GetTargetMethodWithName(Globals.GetEnumeratorMethodName, type, ienumerableInterface); 
                }
            }
        }
 
        static bool IsKnownInterface(Type type)
        { 
            Type typeToCheck = type.IsGenericType ? type.GetGenericTypeDefinition() : type; 
            foreach (Type knownInterfaceType in KnownInterfaces)
            { 
                if (typeToCheck == knownInterfaceType)
                {
                    return true;
                } 
            }
            return false; 
        } 

        ///  
        /// Critical - sets critical properties on CollectionDataContract
        /// Safe - called during schema import/code generation
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal override DataContract BindGenericParameters(DataContract[] paramContracts, Dictionary boundContracts)
        { 
            DataContract boundContract; 
            if(boundContracts.TryGetValue(this, out boundContract))
                return boundContract; 

            CollectionDataContract boundCollectionContract = new CollectionDataContract(Kind);
            boundContracts.Add(this, boundCollectionContract);
            boundCollectionContract.ItemContract = this.ItemContract.BindGenericParameters(paramContracts, boundContracts); 
            boundCollectionContract.IsItemTypeNullable = !boundCollectionContract.ItemContract.IsValueType;
            boundCollectionContract.ItemName = ItemNameSetExplicit ? this.ItemName : boundCollectionContract.ItemContract.StableName.Name; 
            boundCollectionContract.KeyName = this.KeyName; 
            boundCollectionContract.ValueName = this.ValueName;
            boundCollectionContract.StableName = CreateQualifiedName(DataContract.ExpandGenericParameters(XmlConvert.DecodeName(this.StableName.Name), new GenericNameProvider(DataContract.GetClrTypeFullName(this.UnderlyingType), paramContracts)), 
                IsCollectionDataContract(UnderlyingType) ? this.StableName.Namespace : DataContract.GetCollectionNamespace(boundCollectionContract.ItemContract.StableName.Namespace));
            return boundCollectionContract;
        }
 
        internal override DataContract GetValidContract(SerializationMode mode)
        { 
            if (mode == SerializationMode.SharedType) 
            {
                if (SharedTypeContract == null) 
                    DataContract.ThrowTypeNotSerializable(UnderlyingType);
                return SharedTypeContract;
            }
 
            if (InvalidCollectionInSharedContractMessage != null)
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(InvalidCollectionInSharedContractMessage)); 
 
            return this;
        } 

        /// 
        /// Critical - sets the critical IsConstructorCheckRequired property on CollectionDataContract
        ///  
        [SecurityCritical]
        internal override DataContract GetValidContract() 
        { 
            if (this.IsConstructorCheckRequired)
            { 
                if (this.Constructor == null)
                {
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CollectionTypeDoesNotHaveDefaultCtor, DataContract.GetClrTypeFullName(this.UnderlyingType))));
                } 
                else
                { 
                    this.IsConstructorCheckRequired = false; 
                }
            } 
            return this;
        }

        internal override bool IsValidContract(SerializationMode mode) 
        {
            if (mode == SerializationMode.SharedType) 
                return (SharedTypeContract != null); 
            return (InvalidCollectionInSharedContractMessage == null);
        } 

        /// 
        /// Review - calculates whether this collection requires MemberAccessPermission for deserialization.
        ///          since this information is used to determine whether to give the generated code access 
        ///          permissions to private members, any changes to the logic should be reviewed.
        ///  
        [SecurityRequiresReview] 
        internal bool RequiresMemberAccessForRead(SecurityException securityException)
        { 
            if (!IsTypeVisible(UnderlyingType))
            {
                if (securityException != null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString( 
                                SR.PartialTrustCollectionContractTypeNotPublic, 
                                DataContract.GetClrTypeFullName(UnderlyingType)),
                            securityException)); 
                }
                return true;
            }
            if (ItemType != null && !IsTypeVisible(ItemType)) 
            {
                if (securityException != null) 
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString( 
                                SR.PartialTrustCollectionContractTypeNotPublic,
                                DataContract.GetClrTypeFullName(ItemType)),
                            securityException));
                } 
                return true;
            } 
            if (ConstructorRequiresMemberAccess(Constructor)) 
            {
                if (securityException != null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString(
                                SR.PartialTrustCollectionContractNoPublicConstructor, 
                                DataContract.GetClrTypeFullName(UnderlyingType)),
                            securityException)); 
                } 
                return true;
            } 
            if (MethodRequiresMemberAccess(this.AddMethod))
            {
                if (securityException != null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                           new SecurityException(SR.GetString( 
                                   SR.PartialTrustCollectionContractAddMethodNotPublic, 
                                   DataContract.GetClrTypeFullName(UnderlyingType),
                                   this.AddMethod.Name), 
                               securityException));
                }
                return true;
            } 

            return false; 
        } 

        ///  
        /// Review - calculates whether this collection requires MemberAccessPermission for serialization.
        ///          since this information is used to determine whether to give the generated code access
        ///          permissions to private members, any changes to the logic should be reviewed.
        ///  
        [SecurityRequiresReview]
        internal bool RequiresMemberAccessForWrite(SecurityException securityException) 
        { 
            if (!IsTypeVisible(UnderlyingType))
            { 
                if (securityException != null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString( 
                                SR.PartialTrustCollectionContractTypeNotPublic,
                                DataContract.GetClrTypeFullName(UnderlyingType)), 
                            securityException)); 
                }
                return true; 
            }
            if (ItemType != null && !IsTypeVisible(ItemType))
            {
                if (securityException != null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                        new SecurityException(SR.GetString( 
                                SR.PartialTrustCollectionContractTypeNotPublic,
                                DataContract.GetClrTypeFullName(ItemType)), 
                            securityException));
                }
                return true;
            } 

            return false; 
        } 

        internal override bool Equals(object other, Dictionary checkedContracts) 
        {
            if (IsEqualOrChecked(other, checkedContracts))
                return true;
 
            if (base.Equals(other, checkedContracts))
            { 
                CollectionDataContract dataContract = other as CollectionDataContract; 
                if (dataContract != null)
                { 
                    bool thisItemTypeIsNullable = (ItemContract == null) ? false : !ItemContract.IsValueType;
                    bool otherItemTypeIsNullable = (dataContract.ItemContract == null) ? false : !dataContract.ItemContract.IsValueType;
                    return ItemName == dataContract.ItemName &&
                        (IsItemTypeNullable || thisItemTypeIsNullable) == (dataContract.IsItemTypeNullable || otherItemTypeIsNullable) && 
                        ItemContract.Equals(dataContract.ItemContract, checkedContracts);
                } 
            } 
            return false;
        } 

        public override int GetHashCode()
        {
            return base.GetHashCode(); 
        }
 
        public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context) 
        {
            // IsGetOnlyCollection value has already been used to create current collectiondatacontract, value can now be reset. 
            context.IsGetOnlyCollection = false;
            XmlFormatWriterDelegate(xmlWriter, obj, context, this);
        }
 
        public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
        { 
            xmlReader.Read(); 
            object o = null;
            if (context.IsGetOnlyCollection) 
            {
                // IsGetOnlyCollection value has already been used to create current collectiondatacontract, value can now be reset.
                context.IsGetOnlyCollection = false;
                XmlFormatGetOnlyCollectionReaderDelegate(xmlReader, context, CollectionItemName, Namespace, this); 
            }
            else 
            { 
                o = XmlFormatReaderDelegate(xmlReader, context, CollectionItemName, Namespace, this);
            } 
            xmlReader.ReadEndElement();
            return o;
        }
 
        public class DictionaryEnumerator : IEnumerator>
        { 
            IDictionaryEnumerator enumerator; 

            public DictionaryEnumerator(IDictionaryEnumerator enumerator) 
            {
                this.enumerator = enumerator;
            }
 
            public void Dispose()
            { 
            } 

            public bool MoveNext() 
            {
                return enumerator.MoveNext();
            }
 
            public KeyValue Current
            { 
                get {  return new KeyValue(enumerator.Key, enumerator.Value); } 
            }
 
            object System.Collections.IEnumerator.Current
            {
                get { return Current; }
            } 

            public void Reset() 
            { 
                enumerator.Reset();
            } 
        }

        public class GenericDictionaryEnumerator : IEnumerator>
        { 
            IEnumerator> enumerator;
 
            public GenericDictionaryEnumerator(IEnumerator> enumerator) 
            {
                this.enumerator = enumerator; 
            }

            public void Dispose()
            { 
            }
 
            public bool MoveNext() 
            {
                return enumerator.MoveNext(); 
            }

            public KeyValue Current
            { 
                get
                { 
                    KeyValuePair current = enumerator.Current; 
                    return new KeyValue(current.Key, current.Value);
                } 
            }

            object System.Collections.IEnumerator.Current
            { 
                get { return Current; }
            } 
 
            public void Reset()
            { 
                enumerator.Reset();
            }
        }
 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

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