CollectionDataContract.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / CollectionDataContract.cs / 1305376 / 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
    { 
        [Fx.Tag.SecurityNote(Critical = "XmlDictionaryString representing the XML element name for collection items." 
            + "Statically cached and used from IL generated code.")]
        [SecurityCritical] 
        XmlDictionaryString collectionItemName;

        [Fx.Tag.SecurityNote(Critical = "XmlDictionaryString representing the XML namespace for collection items."
            + "Statically cached and used from IL generated code.")] 
        [SecurityCritical]
        XmlDictionaryString childElementNamespace; 
 
        [Fx.Tag.SecurityNote(Critical = "Internal DataContract representing the contract for collection items."
            + "Statically cached and used from IL generated code.")] 
        [SecurityCritical]
        DataContract itemContract;

        [Fx.Tag.SecurityNote(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; 

        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.", 
            Safe = "Doesn't leak anything.")]
        [SecuritySafeCritical]
        internal CollectionDataContract(CollectionKind kind)
            : base(new CollectionDataContractCriticalHelper(kind)) 
        {
            InitCollectionDataContract(this); 
        } 

        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.", 
            Safe = "Doesn't leak anything.")]
        [SecuritySafeCritical]
        internal CollectionDataContract(Type type)
            : base(new CollectionDataContractCriticalHelper(type)) 
        {
            InitCollectionDataContract(this); 
        } 

        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.", 
            Safe = "Doesn't leak anything.")]
        [SecuritySafeCritical]
        internal CollectionDataContract(Type type, DataContract itemContract)
            : base(new CollectionDataContractCriticalHelper(type, itemContract)) 
        {
            InitCollectionDataContract(this); 
        } 

        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.", 
            Safe = "Doesn't leak anything.")]
        [SecuritySafeCritical]
        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)); 
        } 

        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.", 
            Safe = "Doesn't leak anything.")]
        [SecuritySafeCritical]
        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)); 
        } 

        [Fx.Tag.SecurityNote(Critical = "Initializes SecurityCritical field 'helper'.", 
            Safe = "Doesn't leak anything.")]
        [SecuritySafeCritical]
        CollectionDataContract(Type type, string invalidCollectionInSharedContractMessage)
            : base(new CollectionDataContractCriticalHelper(type, invalidCollectionInSharedContractMessage)) 
        {
            InitCollectionDataContract(GetSharedTypeContract(type)); 
        } 

        [Fx.Tag.SecurityNote(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
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical knownInterfaces property.",
                Safe = "knownInterfaces only needs to be protected for write.")]
            [SecuritySafeCritical]
            get { return CollectionDataContractCriticalHelper.KnownInterfaces; } 
        }
 
        internal CollectionKind Kind 
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical kind property.", 
                Safe = "kind only needs to be protected for write.")]
            [SecuritySafeCritical]
            get { return helper.Kind; }
        } 

        internal Type ItemType 
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical itemType property.",
                Safe = "itemType only needs to be protected for write.")] 
            [SecuritySafeCritical]
            get { return helper.ItemType; }
        }
 
        public DataContract ItemContract
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical itemContract property.", 
                Safe = "itemContract only needs to be protected for write.")]
            [SecuritySafeCritical] 
            get { return itemContract ?? helper.ItemContract; }

            [Fx.Tag.SecurityNote(Critical = "Sets the critical itemContract property.")]
            [SecurityCritical] 
            set
            { 
                itemContract = value; 
                helper.ItemContract = value;
            } 
        }

        internal DataContract SharedTypeContract
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical sharedTypeContract property.",
                Safe = "sharedTypeContract only needs to be protected for write.")] 
            [SecuritySafeCritical] 
            get { return helper.SharedTypeContract; }
        } 

        internal string ItemName
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical itemName property.", 
                Safe = "itemName only needs to be protected for write.")]
            [SecuritySafeCritical] 
            get { return helper.ItemName; } 

            [Fx.Tag.SecurityNote(Critical = "Sets the critical itemName property.")] 
            [SecurityCritical]
            set { helper.ItemName = value; }
        }
 
        public XmlDictionaryString CollectionItemName
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical collectionItemName property.", 
                Safe = "collectionItemName only needs to be protected for write.")]
            [SecuritySafeCritical] 
            get { return this.collectionItemName; }
        }

        internal string KeyName 
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical keyName property.", 
                Safe = "keyName only needs to be protected for write.")] 
            [SecuritySafeCritical]
            get { return helper.KeyName; } 

            [Fx.Tag.SecurityNote(Critical = "Sets the critical keyName property.")]
            [SecurityCritical]
            set { helper.KeyName = value; } 
        }
 
        internal string ValueName 
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical valueName property.", 
                Safe = "valueName only needs to be protected for write.")]
            [SecuritySafeCritical]
            get { return helper.ValueName; }
 
            [Fx.Tag.SecurityNote(Critical = "Sets the critical valueName property.")]
            [SecurityCritical] 
            set {  helper.ValueName = value; } 
        }
 
        internal bool IsDictionary
        {
            get { return KeyName != null; }
        } 

        public XmlDictionaryString ChildElementNamespace 
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical childElementNamespace property.",
                Safe = "childElementNamespace only needs to be protected for write; initialized in getter if null.")] 
            [SecuritySafeCritical]
            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 
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical isItemTypeNullable property.",
                Safe = "isItemTypeNullable only needs to be protected for write.")] 
            [SecuritySafeCritical]
            get { return helper.IsItemTypeNullable; }

            [Fx.Tag.SecurityNote(Critical = "Sets the critical isItemTypeNullable property.")] 
            [SecurityCritical]
            set { helper.IsItemTypeNullable = value; } 
        } 

        internal bool IsConstructorCheckRequired 
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical isConstructorCheckRequired property.",
                Safe = "isConstructorCheckRequired only needs to be protected for write.")]
            [SecuritySafeCritical] 
            get { return helper.IsConstructorCheckRequired; }
 
            [Fx.Tag.SecurityNote(Critical = "Sets the critical isConstructorCheckRequired property.")] 
            [SecurityCritical]
            set { helper.IsConstructorCheckRequired = value; } 
        }

        internal MethodInfo GetEnumeratorMethod
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical getEnumeratorMethod property.",
                Safe = "getEnumeratorMethod only needs to be protected for write.")] 
            [SecuritySafeCritical] 
            get { return helper.GetEnumeratorMethod; }
        } 

        internal MethodInfo AddMethod
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical addMethod property.", 
                Safe = "addMethod only needs to be protected for write.")]
            [SecuritySafeCritical] 
            get { return helper.AddMethod; } 
        }
 
        internal ConstructorInfo Constructor
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical constructor property.",
                Safe = "constructor only needs to be protected for write.")] 
            [SecuritySafeCritical]
            get { return helper.Constructor; } 
        } 

        internal override DataContractDictionary KnownDataContracts 
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical knownDataContracts property.",
                Safe = "knownDataContracts only needs to be protected for write.")]
            [SecuritySafeCritical] 
            get { return helper.KnownDataContracts; }
 
            [Fx.Tag.SecurityNote(Critical = "Sets the critical knownDataContracts property.")] 
            [SecurityCritical]
            set { helper.KnownDataContracts = value; } 
        }

        internal string InvalidCollectionInSharedContractMessage
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical invalidCollectionInSharedContractMessage property.",
                Safe = "invalidCollectionInSharedContractMessage only needs to be protected for write.")] 
            [SecuritySafeCritical] 
            get { return helper.InvalidCollectionInSharedContractMessage; }
        } 

        bool ItemNameSetExplicit
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical itemNameSetExplicit property.", 
                Safe = "itemNameSetExplicit only needs to be protected for write.")]
            [SecuritySafeCritical] 
            get { return helper.ItemNameSetExplicit; } 
        }
 
        internal XmlFormatCollectionWriterDelegate XmlFormatWriterDelegate
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical xmlFormatWriterDelegate property.",
                Safe = "xmlFormatWriterDelegate only needs to be protected for write; initialized in getter if null.")] 
            [SecuritySafeCritical]
            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 
        { 
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical xmlFormatReaderDelegate property.",
                Safe = "xmlFormatReaderDelegate only needs to be protected for write; initialized in getter if null.")] 
            [SecuritySafeCritical]
            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
        {
            [Fx.Tag.SecurityNote(Critical = "Fetches the critical xmlFormatGetOnlyCollectionReaderDelegate property.", 
                Safe = "xmlFormatGetOnlyCollectionReaderDelegate only needs to be protected for write; initialized in getter if null.")]
            [SecuritySafeCritical] 
            get 
            {
                if (helper.XmlFormatGetOnlyCollectionReaderDelegate == null) 
                {
                    lock (this)
                    {
                        if (helper.XmlFormatGetOnlyCollectionReaderDelegate == null) 
                        {
                            if (this.OriginalUnderlyingType.IsInterface && (this.Kind == CollectionKind.Enumerable || this.Kind == CollectionKind.Collection || this.Kind == CollectionKind.GenericEnumerable)) 
                            { 
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GetOnlyCollectionMustHaveAddMethod, DataContract.GetClrTypeFullName(this.OriginalUnderlyingType))));
                            } 
                            Fx.Assert(this.AddMethod != null || this.Kind == CollectionKind.Array, "Add method cannot be null if the collection is being used as a get-only property");
                            XmlFormatGetOnlyCollectionReaderDelegate tempDelegate = new XmlFormatReaderGenerator().GenerateGetOnlyCollectionReader(this);
                            Thread.MemoryBarrier();
                            helper.XmlFormatGetOnlyCollectionReaderDelegate = tempDelegate; 
                        }
                    } 
                } 
                return helper.XmlFormatGetOnlyCollectionReaderDelegate;
            } 
        }

        [Fx.Tag.SecurityNote(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.IsNonAttributedTypeValidForSerialization 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]; 
                                if (interfaceTypeToCheck == Globals.TypeOfICollectionGeneric || interfaceTypeToCheck == Globals.TypeOfIListGeneric) 
                                {
                                    addMethod = Globals.TypeOfICollectionGeneric.MakeGenericType(itemType).GetMethod(Globals.AddMethodName); 
                                }
                                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;
                                if (interfaceTypeToCheck == Globals.TypeOfIList) 
                                { 
                                    addMethod = Globals.TypeOfIList.GetMethod(Globals.AddMethodName);
                                } 
                            }
                            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; 
        }
 
        [Fx.Tag.SecurityNote(Critical = "Sets critical properties on CollectionDataContract .", 
            Safe = "Called during schema import/code generation.")]
        [SecuritySafeCritical] 
        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; 
            }
 
            ThrowIfInvalid();
            return this;
        }
 
        void ThrowIfInvalid()
        { 
            if (InvalidCollectionInSharedContractMessage != null) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(InvalidCollectionInSharedContractMessage));
        } 

        internal override DataContract GetValidContract()
        {
            if (this.IsConstructorCheckRequired) 
            {
                CheckConstructor(); 
            } 
            return this;
        } 

        [Fx.Tag.SecurityNote(Critical = "Sets the critical IsConstructorCheckRequired property on CollectionDataContract.",
            Safe = "Does not leak anything.")]
        [SecuritySafeCritical] 
        void CheckConstructor()
        { 
            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; 
            }
        } 
 
        internal override bool IsValidContract(SerializationMode mode)
        { 
            if (mode == SerializationMode.SharedType)
                return (SharedTypeContract != null);
            return (InvalidCollectionInSharedContractMessage == null);
        } 

        [Fx.Tag.SecurityNote(Miscellaneous = 
            "RequiresReview - 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.")] 
        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;
        } 

        [Fx.Tag.SecurityNote(Miscellaneous =
            "RequiresReview - 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.")]
        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.
                        

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