Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / CollectionDataContract.cs / 3 / CollectionDataContract.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.Runtime.Serialization { using System; using System.Collections; using System.Diagnostics; using System.Collections.Generic; using System.IO; using System.Globalization; using System.Reflection; using System.Threading; using System.Xml; using System.Runtime.Serialization.Configuration; using DataContractDictionary=System.Collections.Generic.Dictionary; using System.Security; using System.Security.Permissions; [DataContract(Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")] #if USE_REFEMIT public struct KeyValue #else internal struct KeyValue #endif { K key; V value; internal KeyValue(K key, V value) { this.key = key; this.value = value; } [DataMember(IsRequired = true)] public K Key { get { return key; } set { key = value; } } [DataMember(IsRequired = true)] public V Value { get { return value; } set { this.value = value; } } } internal enum CollectionKind : byte { None, GenericDictionary, Dictionary, GenericList, GenericCollection, List, GenericEnumerable, Collection, Enumerable, Array, } #if USE_REFEMIT public sealed class CollectionDataContract : DataContract #else internal sealed class CollectionDataContract : DataContract #endif { /// /// Critical - XmlDictionaryString representing the XML element name for collection items. /// statically cached and used from IL generated code. /// [SecurityCritical] XmlDictionaryString collectionItemName; ////// Critical - XmlDictionaryString representing the XML namespace for collection items. /// statically cached and used from IL generated code. /// [SecurityCritical] XmlDictionaryString childElementNamespace; ////// Critical - internal DataContract representing the contract for collection items. /// statically cached and used from IL generated code. /// [SecurityCritical] DataContract itemContract; ////// Critical - holds instance of CriticalHelper which keeps state that is cached statically for serialization. /// Static fields are marked SecurityCritical or readonly to prevent /// data from being modified or leaked to other components in appdomain. /// [SecurityCritical] CollectionDataContractCriticalHelper helper; ////// Critical - initializes SecurityCritical field 'helper' /// Safe - doesn't leak anything /// [SecurityCritical, SecurityTreatAsSafe] internal CollectionDataContract(CollectionKind kind) : base(new CollectionDataContractCriticalHelper(kind)) { InitCollectionDataContract(this); } ////// Critical - initializes SecurityCritical field 'helper' /// Safe - doesn't leak anything /// [SecurityCritical, SecurityTreatAsSafe] internal CollectionDataContract(Type type) : base(new CollectionDataContractCriticalHelper(type)) { InitCollectionDataContract(this); } ////// Critical - initializes SecurityCritical field 'helper' /// Safe - doesn't leak anything /// [SecurityCritical, SecurityTreatAsSafe] internal CollectionDataContract(Type type, DataContract itemContract) : base(new CollectionDataContractCriticalHelper(type, itemContract)) { InitCollectionDataContract(this); } ////// Critical - initializes SecurityCritical field 'helper' /// Safe - doesn't leak anything /// [SecurityCritical, SecurityTreatAsSafe] CollectionDataContract(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor) : base(new CollectionDataContractCriticalHelper(type, kind, itemType, getEnumeratorMethod, addMethod, constructor)) { InitCollectionDataContract(GetSharedTypeContract(type)); } ////// Critical - initializes SecurityCritical field 'helper' /// Safe - doesn't leak anything /// [SecurityCritical, SecurityTreatAsSafe] CollectionDataContract(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor, bool isConstructorCheckRequired) : base(new CollectionDataContractCriticalHelper(type, kind, itemType, getEnumeratorMethod, addMethod, constructor, isConstructorCheckRequired)) { InitCollectionDataContract(GetSharedTypeContract(type)); } ////// Critical - initializes SecurityCritical field 'helper' /// Safe - doesn't leak anything /// [SecurityCritical, SecurityTreatAsSafe] CollectionDataContract(Type type, string invalidCollectionInSharedContractMessage) : base(new CollectionDataContractCriticalHelper(type, invalidCollectionInSharedContractMessage)) { InitCollectionDataContract(GetSharedTypeContract(type)); } ////// Critical - initializes SecurityCritical fields; called from all constructors /// [SecurityCritical] void InitCollectionDataContract(DataContract sharedTypeContract) { this.helper = base.Helper as CollectionDataContractCriticalHelper; this.collectionItemName = helper.CollectionItemName; if (helper.Kind == CollectionKind.Dictionary || helper.Kind == CollectionKind.GenericDictionary) { this.itemContract = helper.ItemContract; } this.helper.SharedTypeContract = sharedTypeContract; } void InitSharedTypeContract() { } static Type[] KnownInterfaces { ////// Critical - fetches the critical knownInterfaces property /// Safe - knownInterfaces only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return CollectionDataContractCriticalHelper.KnownInterfaces; } } internal CollectionKind Kind { ////// Critical - fetches the critical kind property /// Safe - kind only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.Kind; } } internal Type ItemType { ////// Critical - fetches the critical itemType property /// Safe - itemType only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.ItemType; } } public DataContract ItemContract { ////// Critical - fetches the critical itemContract property /// Safe - itemContract only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return itemContract ?? helper.ItemContract; } ////// Critical - sets the critical itemContract property /// [SecurityCritical] set { itemContract = value; helper.ItemContract = value; } } internal DataContract SharedTypeContract { ////// Critical - fetches the critical sharedTypeContract property /// Safe - sharedTypeContract only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.SharedTypeContract; } } internal string ItemName { ////// Critical - fetches the critical itemName property /// Safe - itemName only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.ItemName; } ////// Critical - sets the critical itemName property /// [SecurityCritical] set { helper.ItemName = value; } } public XmlDictionaryString CollectionItemName { ////// Critical - fetches the critical collectionItemName property /// Safe - collectionItemName only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return this.collectionItemName; } } internal string KeyName { ////// Critical - fetches the critical keyName property /// Safe - keyName only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.KeyName; } ////// Critical - sets the critical keyName property /// [SecurityCritical] set { helper.KeyName = value; } } internal string ValueName { ////// Critical - fetches the critical valueName property /// Safe - valueName only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.ValueName; } ////// Critical - sets the critical valueName property /// [SecurityCritical] set { helper.ValueName = value; } } internal bool IsDictionary { get { return KeyName != null; } } public XmlDictionaryString ChildElementNamespace { ////// Critical - fetches the critical childElementNamespace property /// Safe - childElementNamespace only needs to be protected for write; initialized in getter if null /// [SecurityCritical, SecurityTreatAsSafe] get { if (this.childElementNamespace == null) { lock (this) { if (this.childElementNamespace == null) { if (helper.ChildElementNamespace == null && !IsDictionary) { XmlDictionaryString tempChildElementNamespace = ClassDataContract.GetChildNamespaceToDeclare(this, ItemType, new XmlDictionary()); Thread.MemoryBarrier(); helper.ChildElementNamespace = tempChildElementNamespace; } this.childElementNamespace = helper.ChildElementNamespace; } } } return childElementNamespace; } } internal bool IsItemTypeNullable { ////// Critical - fetches the critical isItemTypeNullable property /// Safe - isItemTypeNullable only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.IsItemTypeNullable; } ////// Critical - sets the critical isItemTypeNullable property /// [SecurityCritical] set { helper.IsItemTypeNullable = value; } } internal bool IsConstructorCheckRequired { ////// Critical - fetches the critical isConstructorCheckRequired property /// Safe - isConstructorCheckRequired only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.IsConstructorCheckRequired; } ////// Critical - sets the critical isConstructorCheckRequired property /// [SecurityCritical] set { helper.IsConstructorCheckRequired = value; } } internal MethodInfo GetEnumeratorMethod { ////// Critical - fetches the critical getEnumeratorMethod property /// Safe - getEnumeratorMethod only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.GetEnumeratorMethod; } } internal MethodInfo AddMethod { ////// Critical - fetches the critical addMethod property /// Safe - addMethod only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.AddMethod; } } internal ConstructorInfo Constructor { ////// Critical - fetches the critical constructor property /// Safe - constructor only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.Constructor; } } internal override DataContractDictionary KnownDataContracts { ////// Critical - fetches the critical knownDataContracts property /// Safe - knownDataContracts only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.KnownDataContracts; } ////// Critical - sets the critical knownDataContracts property /// [SecurityCritical] set { helper.KnownDataContracts = value; } } internal string InvalidCollectionInSharedContractMessage { ////// Critical - fetches the critical invalidCollectionInSharedContractMessage property /// Safe - invalidCollectionInSharedContractMessage only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.InvalidCollectionInSharedContractMessage; } } bool ItemNameSetExplicit { ////// Critical - fetches the critical itemNameSetExplicit property /// Safe - itemNameSetExplicit only needs to be protected for write /// [SecurityCritical, SecurityTreatAsSafe] get { return helper.ItemNameSetExplicit; } } internal XmlFormatCollectionWriterDelegate XmlFormatWriterDelegate { ////// Critical - fetches the critical xmlFormatWriterDelegate property /// Safe - xmlFormatWriterDelegate only needs to be protected for write; initialized in getter if null /// [SecurityCritical, SecurityTreatAsSafe] get { if (helper.XmlFormatWriterDelegate == null) { lock (this) { if (helper.XmlFormatWriterDelegate == null) { XmlFormatCollectionWriterDelegate tempDelegate = new XmlFormatWriterGenerator().GenerateCollectionWriter(this); Thread.MemoryBarrier(); helper.XmlFormatWriterDelegate = tempDelegate; } } } return helper.XmlFormatWriterDelegate; } } internal XmlFormatCollectionReaderDelegate XmlFormatReaderDelegate { ////// Critical - fetches the critical xmlFormatReaderDelegate property /// Safe - xmlFormatReaderDelegate only needs to be protected for write; initialized in getter if null /// [SecurityCritical, SecurityTreatAsSafe] get { if (helper.XmlFormatReaderDelegate == null) { lock (this) { if (helper.XmlFormatReaderDelegate == null) { XmlFormatCollectionReaderDelegate tempDelegate = new XmlFormatReaderGenerator().GenerateCollectionReader(this); Thread.MemoryBarrier(); helper.XmlFormatReaderDelegate = tempDelegate; } } } return helper.XmlFormatReaderDelegate; } } internal XmlFormatGetOnlyCollectionReaderDelegate XmlFormatGetOnlyCollectionReaderDelegate { ////// Critical - fetches the critical xmlFormatReaderDelegate property /// Safe - xmlFormatReaderDelegate only needs to be protected for write; initialized in getter if null /// [SecurityCritical, SecurityTreatAsSafe] get { if (helper.XmlFormatGetOnlyCollectionReaderDelegate == null) { lock (this) { if (helper.XmlFormatGetOnlyCollectionReaderDelegate == null) { XmlFormatGetOnlyCollectionReaderDelegate tempDelegate = new XmlFormatReaderGenerator().GenerateGetOnlyCollectionReader(this); Thread.MemoryBarrier(); helper.XmlFormatGetOnlyCollectionReaderDelegate = tempDelegate; } } } return helper.XmlFormatGetOnlyCollectionReaderDelegate; } } ////// Critical - holds all state used for (de)serializing collections. /// since the data is cached statically, we lock down access to it. /// [SecurityCritical(SecurityCriticalScope.Everything)] class CollectionDataContractCriticalHelper : DataContract.DataContractCriticalHelper { static Type[] _knownInterfaces; Type itemType; bool isItemTypeNullable; CollectionKind kind; readonly MethodInfo getEnumeratorMethod, addMethod; readonly ConstructorInfo constructor; DataContract itemContract; DataContract sharedTypeContract; DataContractDictionary knownDataContracts; bool isKnownTypeAttributeChecked; string itemName; bool itemNameSetExplicit; XmlDictionaryString collectionItemName; string keyName; string valueName; XmlDictionaryString childElementNamespace; string invalidCollectionInSharedContractMessage; XmlFormatCollectionReaderDelegate xmlFormatReaderDelegate; XmlFormatGetOnlyCollectionReaderDelegate xmlFormatGetOnlyCollectionReaderDelegate; XmlFormatCollectionWriterDelegate xmlFormatWriterDelegate; bool isConstructorCheckRequired = false; internal static Type[] KnownInterfaces { get { if (_knownInterfaces == null) { // Listed in priority order _knownInterfaces = new Type[] { Globals.TypeOfIDictionaryGeneric, Globals.TypeOfIDictionary, Globals.TypeOfIListGeneric, Globals.TypeOfICollectionGeneric, Globals.TypeOfIList, Globals.TypeOfIEnumerableGeneric, Globals.TypeOfICollection, Globals.TypeOfIEnumerable }; } return _knownInterfaces; } } void Init(CollectionKind kind, Type itemType, CollectionDataContractAttribute collectionContractAttribute) { this.kind = kind; if (itemType != null) { this.itemType = itemType; this.isItemTypeNullable = DataContract.IsTypeNullable(itemType); bool isDictionary = (kind == CollectionKind.Dictionary || kind == CollectionKind.GenericDictionary); string itemName = null, keyName = null, valueName = null; if (collectionContractAttribute != null) { if (collectionContractAttribute.IsItemNameSetExplicit) { if (collectionContractAttribute.ItemName == null || collectionContractAttribute.ItemName.Length == 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractItemName, DataContract.GetClrTypeFullName(UnderlyingType)))); itemName = DataContract.EncodeLocalName(collectionContractAttribute.ItemName); itemNameSetExplicit = true; } if (collectionContractAttribute.IsKeyNameSetExplicit) { if (collectionContractAttribute.KeyName == null || collectionContractAttribute.KeyName.Length == 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractKeyName, DataContract.GetClrTypeFullName(UnderlyingType)))); if (!isDictionary) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractKeyNoDictionary, DataContract.GetClrTypeFullName(UnderlyingType), collectionContractAttribute.KeyName))); keyName = DataContract.EncodeLocalName(collectionContractAttribute.KeyName); } if (collectionContractAttribute.IsValueNameSetExplicit) { if (collectionContractAttribute.ValueName == null || collectionContractAttribute.ValueName.Length == 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractValueName, DataContract.GetClrTypeFullName(UnderlyingType)))); if (!isDictionary) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidCollectionContractValueNoDictionary, DataContract.GetClrTypeFullName(UnderlyingType), collectionContractAttribute.ValueName))); valueName = DataContract.EncodeLocalName(collectionContractAttribute.ValueName); } } XmlDictionary dictionary = isDictionary ? new XmlDictionary(5) : new XmlDictionary(3); this.Name = dictionary.Add(this.StableName.Name); this.Namespace = dictionary.Add(this.StableName.Namespace); this.itemName = itemName ?? DataContract.GetStableName(DataContract.UnwrapNullableType(itemType)).Name; this.collectionItemName = dictionary.Add(this.itemName); if (isDictionary) { this.keyName = keyName ?? Globals.KeyLocalName; this.valueName = valueName ?? Globals.ValueLocalName; } } if (collectionContractAttribute != null) { this.IsReference = collectionContractAttribute.IsReference; } } internal CollectionDataContractCriticalHelper(CollectionKind kind) : base() { Init(kind, null, null); } // array internal CollectionDataContractCriticalHelper(Type type) : base(type) { if (type == Globals.TypeOfArray) type = Globals.TypeOfObjectArray; if (type.GetArrayRank() > 1) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SupportForMultidimensionalArraysNotPresent))); this.StableName = DataContract.GetStableName(type); Init(CollectionKind.Array, type.GetElementType(), null); } // array internal CollectionDataContractCriticalHelper(Type type, DataContract itemContract) : base(type) { if (type.GetArrayRank() > 1) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SupportForMultidimensionalArraysNotPresent))); this.StableName = CreateQualifiedName(Globals.ArrayPrefix + itemContract.StableName.Name, itemContract.StableName.Namespace); this.itemContract = itemContract; Init(CollectionKind.Array, type.GetElementType(), null); } // collection internal CollectionDataContractCriticalHelper(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor) : base(type) { if (getEnumeratorMethod == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CollectionMustHaveGetEnumeratorMethod, DataContract.GetClrTypeFullName(type)))); if (addMethod == null && !type.IsInterface) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CollectionMustHaveAddMethod, DataContract.GetClrTypeFullName(type)))); if (itemType == null) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CollectionMustHaveItemType, DataContract.GetClrTypeFullName(type)))); CollectionDataContractAttribute collectionContractAttribute; this.StableName = DataContract.GetCollectionStableName(type, itemType, out collectionContractAttribute); Init(kind, itemType, collectionContractAttribute); this.getEnumeratorMethod = getEnumeratorMethod; this.addMethod = addMethod; this.constructor = constructor; } // collection internal CollectionDataContractCriticalHelper(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor, bool isConstructorCheckRequired) : this(type, kind, itemType, getEnumeratorMethod, addMethod, constructor) { this.isConstructorCheckRequired = isConstructorCheckRequired; } internal CollectionDataContractCriticalHelper(Type type, string invalidCollectionInSharedContractMessage) : base(type) { Init(CollectionKind.Collection, null /*itemType*/, null); this.invalidCollectionInSharedContractMessage = invalidCollectionInSharedContractMessage; } internal CollectionKind Kind { get { return kind; } } internal Type ItemType { get { return itemType; } } internal DataContract ItemContract { get { if (itemContract == null && UnderlyingType != null) { if (IsDictionary) { if (String.CompareOrdinal(KeyName, ValueName) == 0) { DataContract.ThrowInvalidDataContractException( SR.GetString(SR.DupKeyValueName, DataContract.GetClrTypeFullName(UnderlyingType), KeyName), UnderlyingType); } itemContract = ClassDataContract.CreateClassDataContractForKeyValue(ItemType, Namespace, new string[] { KeyName, ValueName }); // Ensure that DataContract gets added to the static DataContract cache for dictionary items DataContract.GetDataContract(ItemType); } else { itemContract = DataContract.GetDataContract(ItemType); } } return itemContract; } set { itemContract = value; } } internal DataContract SharedTypeContract { get { return sharedTypeContract; } set { sharedTypeContract = value; } } internal string ItemName { get { return itemName; } set { itemName = value; } } internal bool IsConstructorCheckRequired { get { return isConstructorCheckRequired; } set { isConstructorCheckRequired = value; } } public XmlDictionaryString CollectionItemName { get { return collectionItemName; } } internal string KeyName { get { return keyName; } set { keyName = value; } } internal string ValueName { get { return valueName; } set { valueName = value; } } internal bool IsDictionary { get { return KeyName != null; } } public XmlDictionaryString ChildElementNamespace { get { return childElementNamespace; } set { childElementNamespace = value; } } internal bool IsItemTypeNullable { get { return isItemTypeNullable; } set { isItemTypeNullable = value; } } internal MethodInfo GetEnumeratorMethod { get { return getEnumeratorMethod; } } internal MethodInfo AddMethod { get { return addMethod; } } internal ConstructorInfo Constructor { get { return constructor; } } internal override DataContractDictionary KnownDataContracts { get { if (!isKnownTypeAttributeChecked && UnderlyingType != null) { lock (this) { if (!isKnownTypeAttributeChecked) { knownDataContracts = DataContract.ImportKnownTypeAttributes(this.UnderlyingType); Thread.MemoryBarrier(); isKnownTypeAttributeChecked = true; } } } return knownDataContracts; } set { knownDataContracts = value; } } internal string InvalidCollectionInSharedContractMessage { get { return invalidCollectionInSharedContractMessage; } } internal bool ItemNameSetExplicit { get { return itemNameSetExplicit; } } internal XmlFormatCollectionWriterDelegate XmlFormatWriterDelegate { get { return xmlFormatWriterDelegate; } set { xmlFormatWriterDelegate = value; } } internal XmlFormatCollectionReaderDelegate XmlFormatReaderDelegate { get { return xmlFormatReaderDelegate; } set { xmlFormatReaderDelegate = value; } } internal XmlFormatGetOnlyCollectionReaderDelegate XmlFormatGetOnlyCollectionReaderDelegate { get { return xmlFormatGetOnlyCollectionReaderDelegate; } set { xmlFormatGetOnlyCollectionReaderDelegate = value; } } } DataContract GetSharedTypeContract(Type type) { if (type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false)) { return this; } // ClassDataContract.IsSerializableTypeValidForSerialization does not need to be called here. It should // never pass because it returns false for types that implement any of CollectionDataContract.KnownInterfaces if (type.IsSerializable || type.IsDefined(Globals.TypeOfDataContractAttribute, false)) { return new ClassDataContract(type); } return null; } internal static bool IsCollectionInterface(Type type) { if (type.IsGenericType) type = type.GetGenericTypeDefinition(); return ((IList)KnownInterfaces).Contains(type); } internal static bool IsCollection(Type type) { Type itemType; return IsCollection(type, out itemType); } internal static bool IsCollection(Type type, out Type itemType) { return IsCollectionHelper(type, out itemType, true /*constructorRequired*/); } internal static bool IsCollection(Type type, bool constructorRequired) { Type itemType; return IsCollectionHelper(type, out itemType, constructorRequired); } static bool IsCollectionHelper(Type type, out Type itemType, bool constructorRequired) { if (type.IsArray && DataContract.GetBuiltInDataContract(type) == null) { itemType = type.GetElementType(); return true; } DataContract dataContract; return IsCollectionOrTryCreate(type, false /*tryCreate*/, out dataContract, out itemType, constructorRequired); } internal static bool TryCreate(Type type, out DataContract dataContract) { Type itemType; return IsCollectionOrTryCreate(type, true /*tryCreate*/, out dataContract, out itemType, true /*constructorRequired*/); } internal static bool CreateGetOnlyCollectionDataContract(Type type, out DataContract dataContract) { Type itemType; if (type.IsArray) { dataContract = new CollectionDataContract(type); return true; } else { return IsCollectionOrTryCreate(type, true /*tryCreate*/, out dataContract, out itemType, false /*constructorRequired*/); } } internal static MethodInfo GetTargetMethodWithName(string name, Type type, Type interfaceType) { InterfaceMapping mapping = type.GetInterfaceMap(interfaceType); for (int i = 0; i < mapping.TargetMethods.Length; i++) { if (mapping.InterfaceMethods[i].Name == name) return mapping.InterfaceMethods[i]; } return null; } static bool IsCollectionOrTryCreate(Type type, bool tryCreate, out DataContract dataContract, out Type itemType, bool constructorRequired) { dataContract = null; itemType = Globals.TypeOfObject; if (DataContract.GetBuiltInDataContract(type) != null) { return HandleIfInvalidCollection(type, tryCreate, false/*hasCollectionDataContract*/, false/*isBaseTypeCollection*/, SR.CollectionTypeCannotBeBuiltIn, null, ref dataContract); } MethodInfo addMethod, getEnumeratorMethod; bool hasCollectionDataContract = IsCollectionDataContract(type); Type baseType = type.BaseType; bool isBaseTypeCollection = (baseType != null && baseType != Globals.TypeOfObject && baseType != Globals.TypeOfValueType && baseType != Globals.TypeOfUri) ? IsCollection(baseType) : false; if (type.IsDefined(Globals.TypeOfDataContractAttribute, false)) { return HandleIfInvalidCollection(type, tryCreate, hasCollectionDataContract, isBaseTypeCollection, SR.CollectionTypeCannotHaveDataContract, null, ref dataContract); } if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(type)) { return false; } if (!Globals.TypeOfIEnumerable.IsAssignableFrom(type)) { return HandleIfInvalidCollection(type, tryCreate, hasCollectionDataContract, isBaseTypeCollection, SR.CollectionTypeIsNotIEnumerable, null, ref dataContract); } if (type.IsInterface) { Type interfaceTypeToCheck = type.IsGenericType ? type.GetGenericTypeDefinition() : type; Type[] knownInterfaces = KnownInterfaces; for (int i = 0; i < knownInterfaces.Length; i++) { if (knownInterfaces[i] == interfaceTypeToCheck) { addMethod = null; if (type.IsGenericType) { Type[] genericArgs = type.GetGenericArguments(); if (interfaceTypeToCheck == Globals.TypeOfIDictionaryGeneric) { itemType = Globals.TypeOfKeyValue.MakeGenericType(genericArgs); addMethod = type.GetMethod(Globals.AddMethodName); getEnumeratorMethod = Globals.TypeOfIEnumerableGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(genericArgs)).GetMethod(Globals.GetEnumeratorMethodName); } else { itemType = genericArgs[0]; getEnumeratorMethod = Globals.TypeOfIEnumerableGeneric.MakeGenericType(itemType).GetMethod(Globals.GetEnumeratorMethodName); } } else { if (interfaceTypeToCheck == Globals.TypeOfIDictionary) { itemType = typeof(KeyValue
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Monitor.cs
- EdmSchemaAttribute.cs
- TdsParserHelperClasses.cs
- TripleDESCryptoServiceProvider.cs
- ProtocolsConfigurationHandler.cs
- InstalledFontCollection.cs
- ListViewPagedDataSource.cs
- Codec.cs
- RefreshEventArgs.cs
- FixedSOMFixedBlock.cs
- PersistChildrenAttribute.cs
- RuntimeHandles.cs
- LinkLabelLinkClickedEvent.cs
- ToolStripButton.cs
- CancellableEnumerable.cs
- SoapExtensionStream.cs
- ToolStripMenuItem.cs
- TimeEnumHelper.cs
- Control.cs
- HtmlWindow.cs
- WorkflowCommandExtensionItem.cs
- XMLUtil.cs
- ProfileProvider.cs
- WizardStepBase.cs
- CodeDomComponentSerializationService.cs
- RewritingValidator.cs
- WindowsTab.cs
- NotifyParentPropertyAttribute.cs
- LinearGradientBrush.cs
- RtfControlWordInfo.cs
- RowSpanVector.cs
- LinkConverter.cs
- SoapObjectWriter.cs
- EncodingStreamWrapper.cs
- TdsParserStateObject.cs
- SharedStatics.cs
- CompilerParameters.cs
- PermissionAttributes.cs
- ChooseAction.cs
- SEHException.cs
- TrackingValidationObjectDictionary.cs
- XhtmlMobileTextWriter.cs
- ImageIndexConverter.cs
- SystemIPv4InterfaceProperties.cs
- Speller.cs
- TextParagraphProperties.cs
- Int64AnimationBase.cs
- GeneratedContractType.cs
- XPathCompileException.cs
- MessageDecoder.cs
- Condition.cs
- RangeValuePatternIdentifiers.cs
- CharKeyFrameCollection.cs
- XmlDataSource.cs
- _FixedSizeReader.cs
- PbrsForward.cs
- SafeFileMapViewHandle.cs
- WebPartConnectionsConfigureVerb.cs
- LoginName.cs
- ApplicationContext.cs
- RegistrationServices.cs
- PeerObject.cs
- KeyGestureValueSerializer.cs
- EtwTrace.cs
- CustomAssemblyResolver.cs
- FusionWrap.cs
- SerializationObjectManager.cs
- Int16.cs
- PointAnimationBase.cs
- FormViewCommandEventArgs.cs
- CorrelationService.cs
- ISAPIWorkerRequest.cs
- CommandField.cs
- OleDbError.cs
- EntityTemplateFactory.cs
- SynchronizingStream.cs
- Lasso.cs
- OrthographicCamera.cs
- PrtTicket_Editor.cs
- ExtractCollection.cs
- DataGridRowHeader.cs
- AutoResetEvent.cs
- DependencyPropertyAttribute.cs
- SimplePropertyEntry.cs
- StandardToolWindows.cs
- SmtpTransport.cs
- EnumerableWrapperWeakToStrong.cs
- XPathChildIterator.cs
- CompareValidator.cs
- BackStopAuthenticationModule.cs
- TraceUtility.cs
- DataSourceGeneratorException.cs
- SubstitutionDesigner.cs
- MessageBox.cs
- ISSmlParser.cs
- SwitchLevelAttribute.cs
- RegionInfo.cs
- SqlTriggerAttribute.cs
- FixedTextSelectionProcessor.cs
- HttpPostedFile.cs