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
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- IOThreadTimer.cs
- ExeConfigurationFileMap.cs
- EventPrivateKey.cs
- WinEventTracker.cs
- HtmlAnchor.cs
- XmlSchemaFacet.cs
- XPathScanner.cs
- ReadOnlyHierarchicalDataSourceView.cs
- DebugHandleTracker.cs
- ManipulationDeltaEventArgs.cs
- ExtendedPropertyCollection.cs
- PassportAuthenticationEventArgs.cs
- OdbcException.cs
- DateTimeOffsetStorage.cs
- TextOnlyOutput.cs
- InterleavedZipPartStream.cs
- GenerateTemporaryTargetAssembly.cs
- RuntimeIdentifierPropertyAttribute.cs
- TextPointerBase.cs
- followingquery.cs
- Interlocked.cs
- EntityType.cs
- OrthographicCamera.cs
- SapiInterop.cs
- Cursor.cs
- DataControlField.cs
- RegularExpressionValidator.cs
- IISMapPath.cs
- ToolboxItemSnapLineBehavior.cs
- CodeIterationStatement.cs
- SharedUtils.cs
- BooleanConverter.cs
- UInt16Converter.cs
- WebBrowserPermission.cs
- HtmlPageAdapter.cs
- LayoutEvent.cs
- BatchStream.cs
- EdgeModeValidation.cs
- UrlMappingCollection.cs
- ContentType.cs
- Adorner.cs
- SqlRetyper.cs
- WsrmMessageInfo.cs
- GeometryHitTestParameters.cs
- DateTimeEditor.cs
- FontDialog.cs
- InfoCardPolicy.cs
- SystemGatewayIPAddressInformation.cs
- EventListener.cs
- ContractNamespaceAttribute.cs
- UnicastIPAddressInformationCollection.cs
- GZipStream.cs
- CodeSubDirectory.cs
- ThreadStaticAttribute.cs
- Rijndael.cs
- SQLByte.cs
- Point.cs
- COM2Enum.cs
- TrustManagerPromptUI.cs
- MemberAssignmentAnalysis.cs
- Library.cs
- CodeAccessPermission.cs
- ReflectEventDescriptor.cs
- Camera.cs
- WorkflowExecutor.cs
- ConsumerConnectionPoint.cs
- XmlObjectSerializerWriteContextComplex.cs
- _NestedSingleAsyncResult.cs
- GroupedContextMenuStrip.cs
- FloaterBaseParagraph.cs
- WebColorConverter.cs
- CatalogZoneDesigner.cs
- AssociatedControlConverter.cs
- ZoomingMessageFilter.cs
- ToolStripDesignerAvailabilityAttribute.cs
- _HTTPDateParse.cs
- TextElement.cs
- Pair.cs
- BindingMemberInfo.cs
- DataGridViewColumn.cs
- DefaultHttpHandler.cs
- oledbmetadatacolumnnames.cs
- Hash.cs
- FrameworkReadOnlyPropertyMetadata.cs
- InteropBitmapSource.cs
- PerfCounters.cs
- SystemIPv4InterfaceProperties.cs
- PropertyChangeTracker.cs
- CodeCatchClause.cs
- ArraySubsetEnumerator.cs
- TextBoxRenderer.cs
- SectionVisual.cs
- DataGridViewCellValueEventArgs.cs
- CorrelationTokenTypeConvertor.cs
- hwndwrapper.cs
- QilReplaceVisitor.cs
- DragDrop.cs
- VisualBrush.cs
- AsyncDataRequest.cs
- DataException.cs