ClassDataContract.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 / ClassDataContract.cs / 4 / ClassDataContract.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.Permissions; 
    using System.Security;
 
#if USE_REFEMIT
    public sealed class ClassDataContract : DataContract
#else
    internal sealed class ClassDataContract : DataContract 
#endif
    { 
        ///  
        /// Review - XmlDictionaryString(s) representing the XML namespaces for class members.
        ///          statically cached and used from IL generated code. should ideally be Critical. 
        ///          marked SecurityRequiresReview to be callable from transparent IL generated code.
        ///          not changed to property to avoid regressing performance; any changes to initalization should be reviewed.
        /// 
        [SecurityRequiresReview] 
        public XmlDictionaryString[] ContractNamespaces;
        ///  
        /// Review - XmlDictionaryString(s) representing the XML element names for class members. 
        ///          statically cached and used from IL generated code. should ideally be Critical.
        ///          marked SecurityRequiresReview to be callable from transparent IL generated code. 
        ///          not changed to property to avoid regressing performance; any changes to initalization should be reviewed.
        /// 
        [SecurityRequiresReview]
        public XmlDictionaryString[] MemberNames; 
        /// 
        /// Review - XmlDictionaryString(s) representing the XML namespaces for class members. 
        ///          statically cached and used when calling IL generated code. should ideally be Critical. 
        ///          marked SecurityRequiresReview to be callable from transparent code.
        ///          not changed to property to avoid regressing performance; any changes to initalization should be reviewed. 
        /// 
        [SecurityRequiresReview]
        public XmlDictionaryString[] MemberNamespaces;
        ///  
        /// Critical - XmlDictionaryString representing the XML namespaces for members of class.
        ///            statically cached and used from IL generated code. 
        ///  
        [SecurityCritical]
        XmlDictionaryString[] childElementNamespaces; 

        /// 
        /// 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] 
        ClassDataContractCriticalHelper helper;
 
        /// 
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal ClassDataContract() : base(new ClassDataContractCriticalHelper()) 
        { 
            InitClassDataContract();
        } 

        /// 
        /// Critical - initializes SecurityCritical field 'helper'
        /// Safe - doesn't leak anything 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal ClassDataContract(Type type) : base(new ClassDataContractCriticalHelper(type)) 
        {
            InitClassDataContract(); 
        }

        /// 
        /// Critical - initializes SecurityCritical field 'helper' 
        /// Safe - doesn't leak anything
        ///  
        [SecurityCritical, SecurityTreatAsSafe] 
        ClassDataContract(Type type, XmlDictionaryString ns, string[] memberNames) : base(new ClassDataContractCriticalHelper(type, ns, memberNames))
        { 
            InitClassDataContract();
        }

        ///  
        /// Critical - initializes SecurityCritical fields; called from all constructors
        ///  
        [SecurityCritical] 
        void InitClassDataContract()
        { 
            this.helper = base.Helper as ClassDataContractCriticalHelper;
            this.ContractNamespaces = helper.ContractNamespaces;
            this.MemberNames = helper.MemberNames;
            this.MemberNamespaces = helper.MemberNamespaces; 
        }
 
        internal ClassDataContract BaseContract 
        {
            ///  
            /// Critical - fetches the critical baseContract property
            /// Safe - baseContract only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.BaseContract; }
            ///  
            /// Critical - sets the critical baseContract property 
            /// 
            [SecurityCritical] 
            set { helper.BaseContract = value; }
        }

        internal List Members 
        {
            ///  
            /// Critical - fetches the critical members property 
            /// Safe - members only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.Members; }
            /// 
            /// Critical - sets the critical members property 
            /// Safe - protected for write if contract has underlyingType
            ///  
            [SecurityCritical] 
            set { helper.Members = value; }
        } 

        public XmlDictionaryString[] ChildElementNamespaces
        {
            ///  
            /// Critical - fetches the critical childElementNamespaces property
            /// Safe - childElementNamespaces only needs to be protected for write; initialized in getter if null 
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get 
            {
                if (this.childElementNamespaces == null)
                {
                    lock (this) 
                    {
                        if (this.childElementNamespaces == null) 
                        { 
                            if (helper.ChildElementNamespaces == null)
                            { 
                                XmlDictionaryString[] tempChildElementamespaces = CreateChildElementNamespaces();
                                Thread.MemoryBarrier();
                                helper.ChildElementNamespaces = tempChildElementamespaces;
                            } 
                            this.childElementNamespaces = helper.ChildElementNamespaces;
                        } 
                    } 
                }
                return this.childElementNamespaces; 
            }
        }

        internal MethodInfo OnSerializing 
        {
            ///  
            /// Critical - fetches the critical onSerializing property 
            /// Safe - onSerializing only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.OnSerializing; }
        }
 
        internal MethodInfo OnSerialized
        { 
            ///  
            /// Critical - fetches the critical onSerialized property
            /// Safe - onSerialized only needs to be protected for write 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.OnSerialized; }
        } 

        internal MethodInfo OnDeserializing 
        { 
            /// 
            /// Critical - fetches the critical onDeserializing property 
            /// Safe - onDeserializing only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.OnDeserializing; } 
        }
 
        internal MethodInfo OnDeserialized 
        {
            ///  
            /// Critical - fetches the critical onDeserialized property
            /// Safe - onDeserialized only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.OnDeserialized; }
        } 
 
        internal MethodInfo ExtensionDataSetMethod
        { 
            /// 
            /// Critical - fetches the critical extensionDataSetMethod property
            /// Safe - extensionDataSetMethod only needs to be protected for write
            ///  
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.ExtensionDataSetMethod; } 
        } 

        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 
            /// Safe - protected for write if contract has underlyingType
            /// 
            [SecurityCritical]
            set { helper.KnownDataContracts = value; } 
        }
 
        internal override bool IsISerializable 
        {
            ///  
            /// Critical - fetches the critical isISerializable property
            /// Safe - isISerializable only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.IsISerializable; }
            ///  
            /// Critical - sets the critical isISerializable property 
            /// Safe - protected for write if contract has underlyingType
            ///  
            [SecurityCritical]
            set { helper.IsISerializable = value; }
        }
 
        internal bool IsNonAttributedType
        { 
            ///  
            /// Critical - fetches the critical IsNonAttributedType property
            /// Safe - IsNonAttributedType only needs to be protected for write 
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.IsNonAttributedType; }
        } 

        internal bool HasDataContract 
        { 
            /// 
            /// Critical - fetches the critical hasDataContract property 
            /// Safe - hasDataContract only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe]
            get { return helper.HasDataContract; } 
        }
 
        internal bool HasExtensionData 
        {
            ///  
            /// Critical - fetches the critical hasExtensionData property
            /// Safe - hasExtensionData only needs to be protected for write
            /// 
            [SecurityCritical, SecurityTreatAsSafe] 
            get { return helper.HasExtensionData; }
        } 
 
        /// 
        /// Critical - fetches information about which constructor should be used to initialize ISerializable types 
        /// Safe - only needs to be protected for write
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        internal ConstructorInfo GetISerializableConstructor() 
        {
            return helper.GetISerializableConstructor(); 
        } 

        ///  
        /// Critical - fetches information about which constructor should be used to initialize non-attributed types that are valid for serialization
        /// Safe - only needs to be protected for write
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        internal ConstructorInfo GetNonAttributedTypeConstructor()
        { 
            return helper.GetNonAttributedTypeConstructor(); 
        }
 
        internal XmlFormatClassWriterDelegate 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)
                        { 
                            XmlFormatClassWriterDelegate tempDelegate = new XmlFormatWriterGenerator().GenerateClassWriter(this); 
                            Thread.MemoryBarrier();
                            helper.XmlFormatWriterDelegate = tempDelegate; 
                        }
                    }
                }
                return helper.XmlFormatWriterDelegate; 
            }
        } 
 
        internal XmlFormatClassReaderDelegate 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)
                        { 
                            XmlFormatClassReaderDelegate tempDelegate = new XmlFormatReaderGenerator().GenerateClassReader(this);
                            Thread.MemoryBarrier(); 
                            helper.XmlFormatReaderDelegate = tempDelegate; 
                        }
                    } 
                }
                return helper.XmlFormatReaderDelegate;
            }
        } 

        internal static ClassDataContract CreateClassDataContractForKeyValue(Type type, XmlDictionaryString ns, string[] memberNames) 
        { 
            return new ClassDataContract(type, ns, memberNames);
        } 

        internal static void CheckAndAddMember(List members, DataMember memberContract, Dictionary memberNamesTable)
        {
            DataMember existingMemberContract; 
            if (memberNamesTable.TryGetValue(memberContract.Name, out existingMemberContract))
            { 
                Type declaringType = memberContract.MemberInfo.DeclaringType; 
                DataContract.ThrowInvalidDataContractException(
                    SR.GetString((declaringType.IsEnum ? SR.DupEnumMemberValue : SR.DupMemberName), 
                        existingMemberContract.MemberInfo.Name,
                        memberContract.MemberInfo.Name,
                        DataContract.GetClrTypeFullName(declaringType),
                        memberContract.Name), 
                    declaringType);
            } 
            memberNamesTable.Add(memberContract.Name, memberContract); 
            members.Add(memberContract);
        } 

        internal static XmlDictionaryString GetChildNamespaceToDeclare(DataContract dataContract, Type childType, XmlDictionary dictionary)
        {
            childType = DataContract.UnwrapNullableType(childType); 
            if (!childType.IsEnum && !Globals.TypeOfIXmlSerializable.IsAssignableFrom(childType)
                && DataContract.GetBuiltInDataContract(childType) == null && childType != Globals.TypeOfDBNull) 
            { 
                string ns = DataContract.GetStableName(childType).Namespace;
                if (ns.Length > 0 && ns != dataContract.Namespace.Value) 
                    return dictionary.Add(ns);
            }
            return null;
        } 

        ///  
        /// RequiresReview - callers may need to depend on isNonAttributedType for a security decision 
        ///            isNonAttributedType must be calculated correctly
        ///            IsNonAttributedTypeValidForSerialization is used as part of the isNonAttributedType calculation and 
        ///            is therefore marked SRR
        /// Safe - does not let caller influence isNonAttributedType calculation; no harm in leaking value
        /// 
        [SecurityRequiresReview] 
        // check whether a corresponding update is required in DataContractCriticalHelper.CreateDataContract
        static internal bool IsNonAttributedTypeValidForSerialization(Type type) 
        { 
            if (type.IsArray)
                return false; 

            if (type.IsEnum)
                return false;
 
            if (type.IsGenericParameter)
                return false; 
 
            if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(type))
                return false; 

            if (type.IsPointer)
                return false;
 
            if (type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false))
                return false; 
 
            Type[] interfaceTypes = type.GetInterfaces();
            foreach (Type interfaceType in interfaceTypes) 
            {
                if (CollectionDataContract.IsCollectionInterface(interfaceType))
                    return false;
            } 

            if (type.IsSerializable) 
                return false; 

            if (Globals.TypeOfISerializable.IsAssignableFrom(type)) 
                return false;

            if (type.IsDefined(Globals.TypeOfDataContractAttribute, false))
                return false; 

            if (type == Globals.TypeOfExtensionDataObject) 
                return false; 

            if (type.IsValueType) 
            {
                return type.IsVisible;
            }
            else 
            {
                return (type.IsVisible && 
                    type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Globals.EmptyTypeArray, null) != null); 
            }
        } 

        XmlDictionaryString[] CreateChildElementNamespaces()
        {
            if (Members == null) 
                return null;
 
            XmlDictionaryString[] baseChildElementNamespaces = null; 
            if (this.BaseContract != null)
                baseChildElementNamespaces = this.BaseContract.ChildElementNamespaces; 
            int baseChildElementNamespaceCount = (baseChildElementNamespaces != null) ? baseChildElementNamespaces.Length : 0;
            XmlDictionaryString[] childElementNamespaces = new XmlDictionaryString[Members.Count + baseChildElementNamespaceCount];
            if (baseChildElementNamespaceCount > 0)
                Array.Copy(baseChildElementNamespaces, 0, childElementNamespaces, 0, baseChildElementNamespaces.Length); 

            XmlDictionary dictionary = new XmlDictionary(); 
            for (int i = 0; i < this.Members.Count; i++) 
            {
                childElementNamespaces[i + baseChildElementNamespaceCount] = GetChildNamespaceToDeclare(this, this.Members[i].MemberType, dictionary); 
            }

            return childElementNamespaces;
        } 

        ///  
        /// Critical - calls critical method on helper 
        /// Safe - doesn't leak anything
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        void EnsureMethodsImported()
        {
            helper.EnsureMethodsImported(); 
        }
 
        public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context) 
        {
            XmlFormatWriterDelegate(xmlWriter, obj, context, this); 
        }

        public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
        { 
            xmlReader.Read();
            object o = XmlFormatReaderDelegate(xmlReader, context, MemberNames, MemberNamespaces); 
            xmlReader.ReadEndElement(); 
            return o;
        } 

        /// 
        /// Review - calculates whether this class 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)
        { 
            EnsureMethodsImported();

            if (!IsTypeVisible(UnderlyingType))
            { 
                if (securityException != null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                        new SecurityException(SR.GetString(
                                SR.PartialTrustDataContractTypeNotPublic, 
                                DataContract.GetClrTypeFullName(UnderlyingType)),
                            securityException));
                }
                return true; 
            }
 
            if (this.BaseContract != null && this.BaseContract.RequiresMemberAccessForRead(securityException)) 
                return true;
 
            if (ConstructorRequiresMemberAccess(GetISerializableConstructor()))
            {
                if (securityException != null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString( 
                                SR.PartialTrustISerializableNoPublicConstructor, 
                                DataContract.GetClrTypeFullName(UnderlyingType)),
                            securityException)); 
                }
                return true;
            }
 

            if (ConstructorRequiresMemberAccess(GetNonAttributedTypeConstructor())) 
            { 
                if (securityException != null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString(
                                SR.PartialTrustNonAttributedSerializableTypeNoPublicConstructor,
                                DataContract.GetClrTypeFullName(UnderlyingType)), 
                            securityException));
                } 
                return true; 
            }
 

            if (MethodRequiresMemberAccess(this.OnDeserializing))
            {
                if (securityException != null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                        new SecurityException(SR.GetString( 
                                SR.PartialTrustDataContractOnDeserializingNotPublic,
                                DataContract.GetClrTypeFullName(UnderlyingType), 
                                this.OnDeserializing.Name),
                            securityException));
                }
                return true; 
            }
 
            if (MethodRequiresMemberAccess(this.OnDeserialized)) 
            {
                if (securityException != null) 
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString(
                                SR.PartialTrustDataContractOnDeserializedNotPublic, 
                                DataContract.GetClrTypeFullName(UnderlyingType),
                                this.OnDeserialized.Name), 
                            securityException)); 
                }
                return true; 
            }

            if (this.Members != null)
            { 
                for (int i = 0; i < this.Members.Count; i++)
                { 
                    if (this.Members[i].RequiresMemberAccessForSet()) 
                    {
                        if (securityException != null) 
                        {
                            if (this.Members[i].MemberInfo is FieldInfo)
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                                    new SecurityException(SR.GetString(
                                            SR.PartialTrustDataContractFieldSetNotPublic, 
                                            DataContract.GetClrTypeFullName(UnderlyingType), 
                                            this.Members[i].MemberInfo.Name),
                                        securityException)); 
                            }
                            else
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                                    new SecurityException(SR.GetString(
                                            SR.PartialTrustDataContractPropertySetNotPublic, 
                                            DataContract.GetClrTypeFullName(UnderlyingType), 
                                            this.Members[i].MemberInfo.Name),
                                        securityException)); 
                            }
                        }
                        return true;
                    } 
                }
            } 
 
            return false;
        } 

        /// 
        /// Review - calculates whether this class 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)
        { 
            EnsureMethodsImported();

            if (!IsTypeVisible(UnderlyingType))
            { 
                if (securityException != null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( 
                        new SecurityException(SR.GetString(
                                SR.PartialTrustDataContractTypeNotPublic, 
                                DataContract.GetClrTypeFullName(UnderlyingType)),
                            securityException));
                }
                return true; 
            }
 
            if (this.BaseContract != null && this.BaseContract.RequiresMemberAccessForWrite(securityException)) 
                return true;
 
            if (MethodRequiresMemberAccess(this.OnSerializing))
            {
                if (securityException != null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString( 
                                SR.PartialTrustDataContractOnSerializingNotPublic, 
                                DataContract.GetClrTypeFullName(this.UnderlyingType),
                                this.OnSerializing.Name), 
                            securityException));
                }
                return true;
            } 

            if (MethodRequiresMemberAccess(this.OnSerialized)) 
            { 
                if (securityException != null)
                { 
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                        new SecurityException(SR.GetString(
                                SR.PartialTrustDataContractOnSerializedNotPublic,
                                DataContract.GetClrTypeFullName(UnderlyingType), 
                                this.OnSerialized.Name),
                            securityException)); 
                } 
                return true;
            } 

            if (this.Members != null)
            {
                for (int i = 0; i < this.Members.Count; i++) 
                {
                    if (this.Members[i].RequiresMemberAccessForGet()) 
                    { 
                        if (securityException != null)
                        { 
                            if (this.Members[i].MemberInfo is FieldInfo)
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                    new SecurityException(SR.GetString( 
                                            SR.PartialTrustDataContractFieldGetNotPublic,
                                            DataContract.GetClrTypeFullName(UnderlyingType), 
                                            this.Members[i].MemberInfo.Name), 
                                        securityException));
                            } 
                            else
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                    new SecurityException(SR.GetString( 
                                            SR.PartialTrustDataContractPropertyGetNotPublic,
                                            DataContract.GetClrTypeFullName(UnderlyingType), 
                                            this.Members[i].MemberInfo.Name), 
                                        securityException));
                            } 
                        }
                        return true;
                    }
                } 
            }
 
            return false; 
        }
 
        /// 
        /// Critical - holds all state used for (de)serializing classes.
        ///            since the data is cached statically, we lock down access to it.
        ///  
        [SecurityCritical(SecurityCriticalScope.Everything)]
        class ClassDataContractCriticalHelper : DataContract.DataContractCriticalHelper 
        { 
            ClassDataContract baseContract;
            List members; 
            MethodInfo onSerializing, onSerialized;
            MethodInfo onDeserializing, onDeserialized;
            MethodInfo extensionDataSetMethod;
            DataContractDictionary knownDataContracts; 
            bool isISerializable;
            bool isKnownTypeAttributeChecked; 
            bool isMethodChecked; 
            bool hasExtensionData;
 
            /// 
            /// in serialization/deserialization we base the decision whether to Demand SerializationFormatter permission on this value and hasDataContract
            /// 
            bool isNonAttributedType; 

            ///  
            /// in serialization/deserialization we base the decision whether to Demand SerializationFormatter permission on this value and isNonAttributedType 
            /// 
            bool hasDataContract; 

            XmlDictionaryString[] childElementNamespaces;
            XmlFormatClassReaderDelegate xmlFormatReaderDelegate;
            XmlFormatClassWriterDelegate xmlFormatWriterDelegate; 

            public XmlDictionaryString[] ContractNamespaces; 
            public XmlDictionaryString[] MemberNames; 
            public XmlDictionaryString[] MemberNamespaces;
 
            internal ClassDataContractCriticalHelper() : base()
            {
            }
 
            internal ClassDataContractCriticalHelper(Type type) : base(type)
            { 
                XmlQualifiedName stableName = GetStableNameAndSetHasDataContract(type); 
                if (type == Globals.TypeOfDBNull)
                { 
                    this.StableName = stableName;
                    this.members = new List();
                    XmlDictionary dictionary = new XmlDictionary(2);
                    this.Name = dictionary.Add(StableName.Name); 
                    this.Namespace = dictionary.Add(StableName.Namespace);
                    this.ContractNamespaces = this.MemberNames = this.MemberNamespaces = new XmlDictionaryString[] { }; 
                    EnsureMethodsImported(); 
                    return;
                } 
                Type baseType = type.BaseType;
                this.isISerializable = (Globals.TypeOfISerializable.IsAssignableFrom(type));
                SetIsNonAttributedType(type);
                if (this.isISerializable) 
                {
                    if (HasDataContract) 
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.ISerializableCannotHaveDataContract, DataContract.GetClrTypeFullName(type)))); 
                    if (baseType != null && !(baseType.IsSerializable && Globals.TypeOfISerializable.IsAssignableFrom(baseType)))
                        baseType = null; 
                }
                this.IsValueType = type.IsValueType;
                if (baseType != null && baseType != Globals.TypeOfObject && baseType != Globals.TypeOfValueType && baseType != Globals.TypeOfUri)
                { 
                    DataContract baseContract = DataContract.GetDataContract(baseType);
                    if (baseContract is CollectionDataContract) 
                        this.BaseContract = ((CollectionDataContract)baseContract).SharedTypeContract as ClassDataContract; 
                    else
                        this.BaseContract = baseContract as ClassDataContract; 
                    if (this.BaseContract != null && this.BaseContract.IsNonAttributedType && !this.isNonAttributedType)
                    {
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError
                            (new InvalidDataContractException(SR.GetString(SR.AttributedTypesCannotInheritFromNonAttributedSerializableTypes, 
                            DataContract.GetClrTypeFullName(type), DataContract.GetClrTypeFullName(baseType))));
                    } 
                } 
                else
                    this.BaseContract = null; 
                hasExtensionData = (Globals.TypeOfIExtensibleDataObject.IsAssignableFrom(type));
                if (hasExtensionData && !HasDataContract && !IsNonAttributedType)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.OnlyDataContractTypesCanHaveExtensionData, DataContract.GetClrTypeFullName(type))));
                if (this.isISerializable) 
                    SetDataContractName(stableName);
                else 
                { 
                    this.StableName = stableName;
                    ImportDataMembers(); 
                    XmlDictionary dictionary = new XmlDictionary(2 + Members.Count);
                    Name = dictionary.Add(StableName.Name);
                    Namespace = dictionary.Add(StableName.Namespace);
 
                    int baseMemberCount = 0;
                    int baseContractCount = 0; 
                    if (BaseContract == null) 
                    {
                        MemberNames = new XmlDictionaryString[Members.Count]; 
                        MemberNamespaces = new XmlDictionaryString[Members.Count];
                        ContractNamespaces = new XmlDictionaryString[1];
                    }
                    else 
                    {
                        baseMemberCount = BaseContract.MemberNames.Length; 
                        MemberNames = new XmlDictionaryString[Members.Count + baseMemberCount]; 
                        Array.Copy(BaseContract.MemberNames, MemberNames, baseMemberCount);
                        MemberNamespaces = new XmlDictionaryString[Members.Count + baseMemberCount]; 
                        Array.Copy(BaseContract.MemberNamespaces, MemberNamespaces, baseMemberCount);
                        baseContractCount = BaseContract.ContractNamespaces.Length;
                        ContractNamespaces = new XmlDictionaryString[1 + baseContractCount];
                        Array.Copy(BaseContract.ContractNamespaces, ContractNamespaces, baseContractCount); 
                    }
                    ContractNamespaces[baseContractCount] = Namespace; 
                    for (int i = 0; i < Members.Count; i++) 
                    {
                        MemberNames[i + baseMemberCount] = dictionary.Add(Members[i].Name); 
                        MemberNamespaces[i + baseMemberCount] = Namespace;
                    }
                }
                EnsureMethodsImported(); 
            }
 
            internal ClassDataContractCriticalHelper(Type type, XmlDictionaryString ns, string[] memberNames) : base(type) 
            {
                this.StableName = new XmlQualifiedName(GetStableNameAndSetHasDataContract(type).Name, ns.Value); 
                ImportDataMembers();
                XmlDictionary dictionary = new XmlDictionary(1 + Members.Count);
                Name = dictionary.Add(StableName.Name);
                Namespace = ns; 
                ContractNamespaces = new XmlDictionaryString[] { Namespace };
                MemberNames = new XmlDictionaryString[Members.Count]; 
                MemberNamespaces = new XmlDictionaryString[Members.Count]; 
                for (int i = 0; i < Members.Count; i++)
                { 
                    Members[i].Name = memberNames[i];
                    MemberNames[i] = dictionary.Add(Members[i].Name);
                    MemberNamespaces[i] = Namespace;
                } 
                EnsureMethodsImported();
            } 
 
            void EnsureIsReferenceImported(Type type)
            { 
                DataContractAttribute dataContractAttribute;
                bool isReference = false;
                bool hasDataContractAttribute = TryGetDCAttribute(type, out dataContractAttribute);
 
                if (BaseContract != null)
                { 
                    if (hasDataContractAttribute && dataContractAttribute.IsReferenceSetExplicit) 
                    {
                        bool baseIsReference = this.BaseContract.IsReference; 
                        if ((baseIsReference && !dataContractAttribute.IsReference) ||
                            (!baseIsReference && dataContractAttribute.IsReference))
                        {
                            DataContract.ThrowInvalidDataContractException( 
                                    SR.GetString(SR.InconsistentIsReference,
                                        DataContract.GetClrTypeFullName(type), 
                                        dataContractAttribute.IsReference, 
                                        DataContract.GetClrTypeFullName(this.BaseContract.UnderlyingType),
                                        this.BaseContract.IsReference), 
                                    type);
                        }
                        else
                        { 
                            isReference = dataContractAttribute.IsReference;
                        } 
                    } 
                    else
                    { 
                        isReference = this.BaseContract.IsReference;
                    }
                }
                else if (hasDataContractAttribute) 
                {
                    if (dataContractAttribute.IsReference) 
                        isReference = dataContractAttribute.IsReference; 
                }
 
                if (isReference && type.IsValueType)
                {
                    DataContract.ThrowInvalidDataContractException(
                            SR.GetString(SR.ValueTypeCannotHaveIsReference, 
                                DataContract.GetClrTypeFullName(type),
                                true, 
                                false), 
                            type);
                    return; 
                }

                this.IsReference = isReference;
            } 

            void ImportDataMembers() 
            { 
                Type type = this.UnderlyingType;
                EnsureIsReferenceImported(type); 
                List tempMembers = new List();
                Dictionary memberNamesTable = new Dictionary();

                MemberInfo[] memberInfos; 
                if (this.isNonAttributedType)
                { 
                    memberInfos = type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); 
                }
                else 
                {
                    memberInfos = type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                }
 
                for (int i = 0; i < memberInfos.Length; i++)
                { 
                    MemberInfo member = memberInfos[i]; 
                    if (HasDataContract)
                    { 
                        object[] memberAttributes = member.GetCustomAttributes(typeof(DataMemberAttribute), false);
                        if (memberAttributes != null && memberAttributes.Length > 0)
                        {
                            if (memberAttributes.Length > 1) 
                                ThrowInvalidDataContractException(SR.GetString(SR.TooManyDataMembers, DataContract.GetClrTypeFullName(member.DeclaringType), member.Name));
 
                            DataMember memberContract = new DataMember(member); 

                            if (member.MemberType == MemberTypes.Property) 
                            {
                                PropertyInfo property = (PropertyInfo)member;

                                MethodInfo getMethod = property.GetGetMethod(true); 
                                if (getMethod != null && IsMethodOverriding(getMethod))
                                    continue; 
                                MethodInfo setMethod = property.GetSetMethod(true); 
                                if (setMethod != null && IsMethodOverriding(setMethod))
                                    continue; 
                                if (getMethod == null)
                                    ThrowInvalidDataContractException(SR.GetString(SR.NoGetMethodForProperty, property.DeclaringType, property.Name));
                                if (setMethod == null)
                                { 
                                    if (!SetIfGetOnlyCollection(memberContract))
                                    { 
                                        ThrowInvalidDataContractException(SR.GetString(SR.NoSetMethodForProperty, property.DeclaringType, property.Name)); 
                                    }
                                } 
                                if (getMethod.GetParameters().Length > 0)
                                    ThrowInvalidDataContractException(SR.GetString(SR.IndexedPropertyCannotBeSerialized, property.DeclaringType, property.Name));
                            }
                            else if (member.MemberType != MemberTypes.Field) 
                                ThrowInvalidDataContractException(SR.GetString(SR.InvalidMember, DataContract.GetClrTypeFullName(type), member.Name));
 
                            DataMemberAttribute memberAttribute = (DataMemberAttribute)memberAttributes[0]; 
                            if (memberAttribute.IsNameSetExplicit)
                            { 
                                if (memberAttribute.Name == null || memberAttribute.Name.Length == 0)
                                    ThrowInvalidDataContractException(SR.GetString(SR.InvalidDataMemberName, member.Name, DataContract.GetClrTypeFullName(type)));
                                memberContract.Name = memberAttribute.Name;
                            } 
                            else
                                memberContract.Name = member.Name; 
 
                            memberContract.Name = DataContract.EncodeLocalName(memberContract.Name);
                            memberContract.IsNullable = DataContract.IsTypeNullable(memberContract.MemberType); 
                            memberContract.IsRequired = memberAttribute.IsRequired;
                            if (memberAttribute.IsRequired && this.IsReference)
                            {
                                ThrowInvalidDataContractException( 
                                    SR.GetString(SR.IsRequiredDataMemberOnIsReferenceDataContractType,
                                    DataContract.GetClrTypeFullName(member.DeclaringType), 
                                    member.Name, true), type); 
                            }
                            memberContract.EmitDefaultValue = memberAttribute.EmitDefaultValue; 
                            memberContract.Order = memberAttribute.Order;
                            CheckAndAddMember(tempMembers, memberContract, memberNamesTable);
                        }
                    } 
                    else if (this.isNonAttributedType)
                    { 
                        FieldInfo field = member as FieldInfo; 
                        PropertyInfo property = member as PropertyInfo;
                        if ((field == null && property == null) || (field != null && field.IsInitOnly)) 
                            continue;

                        object[] memberAttributes = member.GetCustomAttributes(typeof(IgnoreDataMemberAttribute), false);
                        if (memberAttributes != null && memberAttributes.Length > 0) 
                        {
                            if (memberAttributes.Length > 1) 
                                ThrowInvalidDataContractException(SR.GetString(SR.TooManyIgnoreDataMemberAttributes, DataContract.GetClrTypeFullName(member.DeclaringType), member.Name)); 
                            else
                                continue; 
                        }
                        DataMember memberContract = new DataMember(member);
                        if (property != null)
                        { 
                            MethodInfo getMethod = property.GetGetMethod();
                            if (getMethod == null || IsMethodOverriding(getMethod) || getMethod.GetParameters().Length > 0) 
                                continue; 

                            MethodInfo setMethod = property.GetSetMethod(true); 
                            if (setMethod == null)
                            {
                                if (!SetIfGetOnlyCollection(memberContract))
                                    continue; 
                            }
                            else 
                            { 
                                if (!setMethod.IsPublic || IsMethodOverriding(setMethod))
                                    continue; 
                            }

                            //skip ExtensionData member of type ExtensionDataObject if IExtensibleDataObject is implemented in non-attributed type
                            if (this.hasExtensionData && memberContract.MemberType == Globals.TypeOfExtensionDataObject 
                                && member.Name == Globals.ExtensionDataObjectPropertyName)
                                continue; 
                        } 

                        memberContract.Name = DataContract.EncodeLocalName(member.Name); 
                        memberContract.IsNullable = DataContract.IsTypeNullable(memberContract.MemberType);
                        CheckAndAddMember(tempMembers, memberContract, memberNamesTable);
                    }
                    else 
                    {
                        FieldInfo field = member as FieldInfo; 
                        if (field != null && !field.IsNotSerialized) 
                        {
                            DataMember memberContract = new DataMember(member); 

                            memberContract.Name = DataContract.EncodeLocalName(member.Name);
                            object[] optionalFields = field.GetCustomAttributes(Globals.TypeOfOptionalFieldAttribute, false);
                            if (optionalFields == null || optionalFields.Length == 0) 
                            {
                                if (this.IsReference) 
                                { 
                                    ThrowInvalidDataContractException(
                                        SR.GetString(SR.NonOptionalFieldMemberOnIsReferenceSerializableType, 
                                        DataContract.GetClrTypeFullName(member.DeclaringType),
                                        member.Name, true), type);
                                }
                                memberContract.IsRequired = true; 
                            }
                            memberContract.IsNullable = DataContract.IsTypeNullable(memberContract.MemberType); 
                            CheckAndAddMember(tempMembers, memberContract, memberNamesTable); 
                        }
                    } 
                }
                if (tempMembers.Count > 1)
                    tempMembers.Sort(DataMemberComparer.Singleton);
 
                SetIfMembersHaveConflict(tempMembers);
 
                Thread.MemoryBarrier(); 
                members = tempMembers;
            } 

            bool SetIfGetOnlyCollection(DataMember memberContract)
            {
                //OK to call IsCollection here since the use of surrogated collection types is not supported in get-only scenarios 
                if (CollectionDataContract.IsCollection(memberContract.MemberType, false /*isConstructorRequired*/) && !memberContract.MemberType.IsValueType)
                { 
                    memberContract.IsGetOnlyCollection = true; 
                    return true;
                } 
                return false;
            }

            void SetIfMembersHaveConflict(List members) 
            {
                if (BaseContract == null) 
                    return; 

                int baseTypeIndex = 0; 
                List membersInHierarchy = new List();
                foreach (DataMember member in members)
                {
                    membersInHierarchy.Add(new Member(member, this.StableName.Namespace, baseTypeIndex)); 
                }
                ClassDataContract currContract = BaseContract; 
                while (currContract != null) 
                {
                    baseTypeIndex++; 
                    foreach (DataMember member in currContract.Members)
                    {
                        membersInHierarchy.Add(new Member(member, currContract.StableName.Namespace, baseTypeIndex));
                    } 
                    currContract = currContract.BaseContract;
                } 
 
                IComparer comparer = DataMemberConflictComparer.Singleton;
                membersInHierarchy.Sort(comparer); 

                for (int i = 0; i < membersInHierarchy.Count - 1; i++)
                {
                    int startIndex = i; 
                    int endIndex = i;
                    bool hasConflictingType = false; 
                    while (endIndex < membersInHierarchy.Count - 1 
                        && String.CompareOrdinal(membersInHierarchy[endIndex].member.Name, membersInHierarchy[endIndex + 1].member.Name) == 0
                        && String.CompareOrdinal(membersInHierarchy[endIndex].ns, membersInHierarchy[endIndex + 1].ns) == 0) 
                    {
                        membersInHierarchy[endIndex].member.ConflictingMember = membersInHierarchy[endIndex + 1].member;
                        if (!hasConflictingType)
                        { 
                            if (membersInHierarchy[endIndex + 1].member.HasConflictingNameAndType)
                            { 
                                hasConflictingType = true; 
                            }
                            else 
                            {
                                hasConflictingType = (membersInHierarchy[endIndex].member.MemberType != membersInHierarchy[endIndex + 1].member.MemberType);
                            }
                        } 
                        endIndex++;
                    } 
 
                    if (hasConflictingType)
                    { 
                        for (int j = startIndex; j <= endIndex; j++)
                        {
                            membersInHierarchy[j].member.HasConflictingNameAndType = true;
                        } 
                    }
 
                    i = endIndex + 1; 
                }
            } 

            /// 
            /// Critical - sets the critical hasDataContract field
            /// Safe - uses a trusted critical API (DataContract.GetStableName) to calculate the value 
            ///        does not accept the value from the caller
            ///  
            [SecurityCritical, SecurityTreatAsSafe] 
            XmlQualifiedName GetStableNameAndSetHasDataContract(Type type)
            { 
                return DataContract.GetStableName(type, out this.hasDataContract);
            }

            ///  
            /// RequiresReview - marked SRR because callers may need to depend on isNonAttributedType for a security decision
            ///            isNonAttributedType must be calculated correctly 
            ///            SetIsNonAttributedType should not be called before GetStableNameAndSetHasDataContract since it 
            ///            is dependent on the correct calculation of hasDataContract
            /// Safe - does not let caller influence isNonAttributedType calculation; no harm in leaking value 
            /// 
            [SecurityRequiresReview]
            void SetIsNonAttributedType(Type type)
            { 
                this.isNonAttributedType = !type.IsSerializable && !this.hasDataContract && IsNonAttributedTypeValidForSerialization(type);
            } 
 
            static bool IsMethodOverriding(MethodInfo method)
            { 
                return method.IsVirtual && ((method.Attributes & MethodAttributes.NewSlot) == 0);
            }

            internal void EnsureMethodsImported() 
            {
                if (!isMethodChecked && UnderlyingType != null) 
                { 
                    lock (this)
                    { 
                        if (!isMethodChecked)
                        {
                            Type type = this.UnderlyingType;
                            MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ); 
                            for (int i=0;i Members
            {
                get { return members; } 
                set { members = value; }
            } 
 
            internal MethodInfo OnSerializing
            { 
                get
                {
                    EnsureMethodsImported();
                    return onSerializing; 
                }
            } 
 
            internal MethodInfo OnSerialized
            { 
                get
                {
                    EnsureMethodsImported();
                    return onSerialized; 
                }
            } 
 
            internal MethodInfo OnDeserializing
            { 
                get
                {
                    EnsureMethodsImported();
                    return onDeserializing; 
                }
            } 
 
            internal MethodInfo OnDeserialized
            { 
                get
                {
                    EnsureMethodsImported();
                    return onDeserialized; 
                }
            } 
 
            internal MethodInfo ExtensionDataSetMethod
            { 
                get
                {
                    EnsureMethodsImported();
                    return extensionDataSetMethod; 
                }
            } 
 
            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 override bool IsISerializable
            {
                get { return isISerializable; } 
                set { isISerializable = value; }
            } 
 
            internal bool HasDataContract
            { 
                get { return hasDataContract; }
            }

            internal bool HasExtensionData 
            {
                get { return hasExtensionData; } 
            } 

            internal bool IsNonAttributedType 
            {
                get { return isNonAttributedType; }
            }
 
            internal ConstructorInfo GetISerializableConstructor()
            { 
                if (!IsISerializable) 
                    return null;
 
                ConstructorInfo ctor = UnderlyingType.GetConstructor(Globals.ScanAllMembers, null, SerInfoCtorArgs, null);
                if (ctor == null)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString(SR.SerializationInfo_ConstructorNotFound, DataContract.GetClrTypeFullName(UnderlyingType))));
 
                return ctor;
            } 
 
            internal ConstructorInfo GetNonAttributedTypeConstructor()
            { 
                if (!this.IsNonAttributedType)
                    return null;

                Type type = UnderlyingType; 

                if (type.IsValueType) 
                    return null; 

                ConstructorInfo ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Globals.EmptyTypeArray, null); 
                if (ctor == null)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.NonAttributedSerializableTypesMustHaveDefaultConstructor, DataContract.GetClrTypeFullName(type))));

                return ctor; 
            }
 
            internal XmlFormatClassWriterDelegate XmlFormatWriterDelegate 
            {
                get { return xmlFormatWriterDelegate; } 
                set { xmlFormatWriterDelegate = value; }
            }

            internal XmlFormatClassReaderDelegate XmlFormatReaderDelegate 
            {
                get { return xmlFormatReaderDelegate; } 
                set { xmlFormatReaderDelegate = value; } 
            }
 
            public XmlDictionaryString[] ChildElementNamespaces
            {
                get { return childElementNamespaces; }
                set { childElementNamespaces = value; } 
            }
 
            static Type[] serInfoCtorArgs; 
            static Type[] SerInfoCtorArgs
            { 
                get
                {
                    if (serInfoCtorArgs == null)
                        serInfoCtorArgs = new Type[] { typeof(SerializationInfo), typeof(StreamingContext) }; 
                    return serInfoCtorArgs;
                } 
            } 

            internal struct Member 
            {
                internal Member(DataMember member, string ns, int baseTypeIndex)
                {
                    this.member = member; 
                    this.ns = ns;
                    this.baseTypeIndex = baseTypeIndex; 
                } 
                internal DataMember member;
                internal string ns; 
                internal int baseTypeIndex;
            }

            internal class DataMemberConflictComparer : IComparer 
            {
                public int Compare(Member x, Member y) 
                { 
                    int nsCompare = String.CompareOrdinal(x.ns, y.ns);
                    if (nsCompare != 0) 
                        return nsCompare;

                    int nameCompare = String.CompareOrdinal(x.member.Name, y.member.Name);
                    if (nameCompare != 0) 
                        return nameCompare;
 
                    return x.baseTypeIndex - y.baseTypeIndex; 
                }
 
                internal static DataMemberConflictComparer Singleton = new DataMemberConflictComparer();
            }

        } 

        ///  
        /// Critical - sets critical properties on ClassDataContract 
        /// Safe - called during schema import/code generation
        ///  
        [SecurityCritical, SecurityTreatAsSafe]
        internal override DataContract BindGenericParameters(DataContract[] paramContracts, Dictionary boundContracts)
        {
            Type type = UnderlyingType; 
            if(!type.IsGenericType || !type.ContainsGenericParameters)
                return this; 
 
            lock(this)
            { 
                DataContract boundContract;
                if(boundContracts.TryGetValue(this, out boundContract))
                    return boundContract;
 
                ClassDataContract boundClassContract = new ClassDataContract();
                boundContracts.Add(this, boundClassContract); 
                XmlQualifiedName stableName; 
                object[] genericParams;
                if(type.IsGenericTypeDefinition) 
                {
                    stableName = this.StableName;
                    genericParams = paramContracts;
                } 
                else
                { 
                    //partial Generic: Construct stable name from its open generic type definition 
                    stableName = DataContract.GetStableName(type.GetGenericTypeDefinition());
                    Type[] paramTypes = type.GetGenericArguments(); 
                    genericParams = new object[paramTypes.Length];
                    for(int i=0;i(Members.Count); 
                    foreach(DataMember member in Members)
                        boundClassContract.Members.Add(member.BindGenericParameters(paramContracts, boundContracts));
                }
                return boundClassContract; 
            }
        } 
 
        internal override bool Equals(object other, Dictionary checkedContracts)
        { 
            if (IsEqualOrChecked(other, checkedContracts))
                return true;

            if (base.Equals(other, checkedContracts)) 
            {
                ClassDataContract dataContract = other as ClassDataContract; 
                if (dataContract != null) 
                {
                    if (IsISerializable) 
                    {
                        if (!dataContract.IsISerializable)
                            return false;
                    } 
                    else
                    { 
                        if (dataContract.IsISerializable) 
                            return false;
 
                        if (Members == null)
                        {
                            if (dataContract.Members != null)
                                return false; 
                        }
                        else if (dataContract.Members == null) 
                            return false; 
                        else
                        { 
                            if (Members.Count != dataContract.Members.Count)
                                return false;

                            for (int i = 0; i < Members.Count; i++) 
                            {
                                if (!Members[i].Equals(dataContract.Members[i], checkedContracts)) 
                                    return false; 
                            }
                        } 
                    }

                    if (BaseContract == null)
                        return (dataContract.BaseContract == null); 
                    else if (dataContract.BaseContract == null)
                        return false; 
                    else 
                        return BaseContract.Equals(dataContract.BaseContract, checkedContracts);
                } 
            }
            return false;
        }
 
        public override int GetHashCode()
        { 
            return base.GetHashCode(); 
        }
 
        internal class DataMemberComparer : IComparer
        {
            public int Compare(DataMember x, DataMember y)
            { 
                int orderCompare = x.Order - y.Order;
                if (orderCompare != 0) 
                    return orderCompare; 

                return String.CompareOrdinal(x.Name, y.Name); 
            }

            internal static DataMemberComparer Singleton = new DataMemberComparer();
        } 
    }
} 
 

// 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