1 // Licensed to the .NET Foundation under one or more agreements. 2 // The .NET Foundation licenses this file to you under the MIT license. 3 // See the LICENSE file in the project root for more information. 4 5 using System; 6 using System.Collections; 7 using System.Collections.Generic; 8 using System.Globalization; 9 using System.Reflection; 10 using System.Runtime.Serialization; 11 using System.Security.Cryptography; 12 using System.Text; 13 using System.Xml; 14 using System.Xml.Schema; 15 using System.Xml.Serialization; 16 17 namespace SerializationTestTypes 18 { 19 interface IGenericNameProvider 20 { GetParameterCount()21 int GetParameterCount(); GetParameterName(int paramIndex)22 string GetParameterName(int paramIndex); GetNamespaces()23 string GetNamespaces(); GetGenericTypeName()24 string GetGenericTypeName(); 25 bool ParametersFromBuiltInNamespaces { get; } 26 } 27 28 class GenericNameProvider : IGenericNameProvider 29 { 30 string genericTypeName; 31 object[] genericParams; GenericNameProvider(Type type)32 internal GenericNameProvider(Type type) 33 : this(type.GetGenericTypeDefinition().FullName, type.GetGenericArguments()) 34 { 35 } 36 GenericNameProvider(string genericTypeName, object[] genericParams)37 internal GenericNameProvider(string genericTypeName, object[] genericParams) 38 { 39 this.genericTypeName = genericTypeName; 40 this.genericParams = new object[genericParams.Length]; 41 genericParams.CopyTo(this.genericParams, 0); 42 } 43 GetParameterCount()44 public int GetParameterCount() 45 { 46 return genericParams.Length; 47 } 48 GetParameterName(int paramIndex)49 public string GetParameterName(int paramIndex) 50 { 51 return GetStableName(paramIndex).Name; 52 } 53 GetNamespaces()54 public string GetNamespaces() 55 { 56 StringBuilder namespaces = new StringBuilder(); 57 for (int j = 0; j < GetParameterCount(); j++) 58 namespaces.Append(" ").Append(GetStableName(j).Namespace); 59 return namespaces.ToString(); 60 } 61 GetGenericTypeName()62 public string GetGenericTypeName() 63 { 64 return genericTypeName; 65 } 66 67 public bool ParametersFromBuiltInNamespaces 68 { 69 get 70 { 71 bool parametersFromBuiltInNamespaces = true; 72 for (int j = 0; j < GetParameterCount(); j++) 73 { 74 if (parametersFromBuiltInNamespaces) 75 parametersFromBuiltInNamespaces = DataContract.IsBuiltInNamespace(GetStableName(j).Namespace); 76 else 77 break; 78 } 79 return parametersFromBuiltInNamespaces; 80 } 81 } 82 GetStableName(int i)83 XmlQualifiedName GetStableName(int i) 84 { 85 object o = genericParams[i]; 86 XmlQualifiedName qname = o as XmlQualifiedName; 87 if (qname == null) 88 { 89 Type paramType = o as Type; 90 if (paramType != null) 91 genericParams[i] = qname = DataContract.GetStableName(paramType); 92 else 93 genericParams[i] = qname = ((DataContract)o).StableName; 94 } 95 return qname; 96 } 97 } 98 99 class GenericInfo : IGenericNameProvider 100 { 101 string genericTypeName; 102 XmlQualifiedName stableName; 103 List<GenericInfo> paramGenericInfos; 104 GenericInfo(XmlQualifiedName stableName, string genericTypeName)105 internal GenericInfo(XmlQualifiedName stableName, string genericTypeName) 106 { 107 this.stableName = stableName; 108 this.genericTypeName = genericTypeName; 109 } 110 Add(GenericInfo actualParamInfo)111 internal void Add(GenericInfo actualParamInfo) 112 { 113 if (paramGenericInfos == null) 114 paramGenericInfos = new List<GenericInfo>(); 115 paramGenericInfos.Add(actualParamInfo); 116 } 117 GetExpandedStableName()118 internal XmlQualifiedName GetExpandedStableName() 119 { 120 if (paramGenericInfos == null) 121 return stableName; 122 return new XmlQualifiedName(DataContract.ExpandGenericParameters(XmlConvert.DecodeName(stableName.Name), this), stableName.Namespace); 123 } 124 GetStableNamespace()125 internal string GetStableNamespace() 126 { 127 return stableName.Namespace; 128 } 129 130 internal XmlQualifiedName StableName 131 { 132 get { return stableName; } 133 } 134 135 internal IList<GenericInfo> Parameters 136 { 137 get { return paramGenericInfos; } 138 } 139 GetParameterCount()140 public int GetParameterCount() 141 { 142 return paramGenericInfos.Count; 143 } 144 GetParameterName(int paramIndex)145 public string GetParameterName(int paramIndex) 146 { 147 return paramGenericInfos[paramIndex].GetExpandedStableName().Name; 148 } 149 GetNamespaces()150 public string GetNamespaces() 151 { 152 StringBuilder namespaces = new StringBuilder(); 153 for (int j = 0; j < paramGenericInfos.Count; j++) 154 namespaces.Append(" ").Append(paramGenericInfos[j].GetStableNamespace()); 155 return namespaces.ToString(); 156 } 157 GetGenericTypeName()158 public string GetGenericTypeName() 159 { 160 return genericTypeName; 161 } 162 163 public bool ParametersFromBuiltInNamespaces 164 { 165 get 166 { 167 bool parametersFromBuiltInNamespaces = true; 168 for (int j = 0; j < paramGenericInfos.Count; j++) 169 { 170 if (parametersFromBuiltInNamespaces) 171 parametersFromBuiltInNamespaces = DataContract.IsBuiltInNamespace(paramGenericInfos[j].GetStableNamespace()); 172 else 173 break; 174 } 175 return parametersFromBuiltInNamespaces; 176 } 177 } 178 179 } 180 181 class RuntimeTypeHandleEqualityComparer : IEqualityComparer<RuntimeTypeHandle> 182 { 183 static RuntimeTypeHandleEqualityComparer comparer; 184 185 static public RuntimeTypeHandleEqualityComparer Comparer 186 { 187 get 188 { 189 if (comparer == null) 190 { 191 comparer = new RuntimeTypeHandleEqualityComparer(); 192 } 193 194 return comparer; 195 } 196 } 197 Equals(RuntimeTypeHandle x, RuntimeTypeHandle y)198 public bool Equals(RuntimeTypeHandle x, RuntimeTypeHandle y) 199 { 200 return x.Equals(y); 201 } 202 GetHashCode(RuntimeTypeHandle obj)203 public int GetHashCode(RuntimeTypeHandle obj) 204 { 205 return obj.GetHashCode(); 206 } 207 } 208 209 public class DataContract 210 { 211 static Dictionary<RuntimeTypeHandle, DataContract> cache = new Dictionary<RuntimeTypeHandle, DataContract>(RuntimeTypeHandleEqualityComparer.Comparer); 212 static MD5CryptoServiceProvider md5 = null; 213 214 Type underlyingType; 215 bool isValueType; 216 XmlQualifiedName stableName; 217 protected internal bool supportCollectionDataContract; 218 GetDataContract(Type type, bool supportCollectionDataContract)219 public static DataContract GetDataContract(Type type, bool supportCollectionDataContract) 220 { 221 return GetDataContract(type.TypeHandle, type, supportCollectionDataContract); 222 } 223 IsBuiltInNamespace(string ns)224 internal static bool IsBuiltInNamespace(string ns) 225 { 226 return (ns == Globals.SchemaNamespace || ns == Globals.SerializationNamespace); 227 } 228 ExpandGenericParameters(string format, IGenericNameProvider genericNameProvider)229 internal static string ExpandGenericParameters(string format, IGenericNameProvider genericNameProvider) 230 { 231 string digest = null; 232 StringBuilder typeName = new StringBuilder(); 233 for (int i = 0; i < format.Length; i++) 234 { 235 char ch = format[i]; 236 if (ch == '{') 237 { 238 i++; 239 int start = i; 240 for (; i < format.Length; i++) 241 if (format[i] == '}') 242 break; 243 if (i == format.Length) 244 throw new ArgumentException("GenericNameBraceMismatch"); 245 if (format[start] == '#' && i == (start + 1)) 246 { 247 if (!genericNameProvider.ParametersFromBuiltInNamespaces) 248 { 249 if (digest == null) 250 digest = GetNamespacesDigest(String.Format(CultureInfo.InvariantCulture, " {0}{1}", genericNameProvider.GetParameterCount(), genericNameProvider.GetNamespaces())); 251 typeName.Append(digest); 252 } 253 } 254 else 255 { 256 int paramIndex; 257 if (!Int32.TryParse(format.Substring(start, i - start), out paramIndex) || paramIndex < 0 || paramIndex >= genericNameProvider.GetParameterCount()) 258 throw new ArgumentException("GenericParameterNotValid"); 259 typeName.Append(genericNameProvider.GetParameterName(paramIndex)); 260 } 261 } 262 else 263 typeName.Append(ch); 264 } 265 return typeName.ToString(); 266 } 267 GetNamespacesDigest(string namespaces)268 private static string GetNamespacesDigest(string namespaces) 269 { 270 if (md5 == null) 271 md5 = new MD5CryptoServiceProvider(); 272 byte[] namespaceBytes = Encoding.UTF8.GetBytes(namespaces); 273 byte[] digestBytes = md5.ComputeHash(namespaceBytes); 274 char[] digestChars = new char[24]; 275 const int digestLen = 6; 276 int digestCharsLen = Convert.ToBase64CharArray(digestBytes, 0, digestLen, digestChars, 0); 277 StringBuilder digest = new StringBuilder(); 278 for (int i = 0; i < digestCharsLen; i++) 279 { 280 char ch = digestChars[i]; 281 switch (ch) 282 { 283 case '=': 284 break; 285 case '/': 286 digest.Append("_S"); 287 break; 288 case '+': 289 digest.Append("_P"); 290 break; 291 default: 292 digest.Append(ch); 293 break; 294 } 295 } 296 return digest.ToString(); 297 } 298 BindGenericParameters(DataContract[] paramContracts, Dictionary<DataContract, DataContract> boundContracts)299 internal virtual DataContract BindGenericParameters(DataContract[] paramContracts, Dictionary<DataContract, DataContract> boundContracts) 300 { 301 return this; 302 } 303 GetDataContract(RuntimeTypeHandle typeHandle, Type type)304 public static DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type) 305 { 306 return GetDataContract(typeHandle, type, false); 307 } 308 GetDataContract(RuntimeTypeHandle typeHandle, Type type, bool supportCollectionDataContract)309 public static DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type, bool supportCollectionDataContract) 310 { 311 DataContract dataContract = null; 312 if (!cache.TryGetValue(typeHandle, out dataContract)) 313 { 314 lock (cache) 315 { 316 if (!cache.TryGetValue(typeHandle, out dataContract)) 317 { 318 if (type == null) 319 type = Type.GetTypeFromHandle(typeHandle); 320 type = UnwrapNullableType(type); 321 dataContract = CreateDataContract(type, supportCollectionDataContract); 322 cache.Add(typeHandle, dataContract); 323 } 324 } 325 } 326 return dataContract; 327 } 328 UnwrapNullableType(Type type)329 internal static Type UnwrapNullableType(Type type) 330 { 331 if (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfNullable) 332 type = type.GetGenericArguments()[0]; 333 return type; 334 } 335 CreateDataContract(Type type, bool supportCollectionDataContract)336 public static DataContract CreateDataContract(Type type, bool supportCollectionDataContract) 337 { 338 DataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(type); 339 340 if (primitiveContract != null) 341 return primitiveContract; 342 343 if (type.IsArray) 344 return new ArrayDataContract(type); 345 346 if (type.IsEnum) 347 return new EnumDataContract(type); 348 if (supportCollectionDataContract) 349 { 350 DataContract collectionDataContract; 351 Type itemType; 352 if (CollectionDataContract.IsCollectionOrTryCreate(type, true, out collectionDataContract, out itemType, true)) 353 { 354 return collectionDataContract; 355 } 356 } 357 return new ClassDataContract(type); 358 } 359 GetStableName(Type type)360 public static XmlQualifiedName GetStableName(Type type) 361 { 362 bool hasDataContract; 363 return GetStableName(type, out hasDataContract); 364 } 365 GetStableName(Type type, bool supportCollectionDataContract)366 public static XmlQualifiedName GetStableName(Type type, bool supportCollectionDataContract) 367 { 368 bool hasDataContract; 369 return GetStableName(type, out hasDataContract, supportCollectionDataContract); 370 } 371 GetStableName(Type type, out bool hasDataContract)372 public static XmlQualifiedName GetStableName(Type type, out bool hasDataContract) 373 { 374 return GetStableName(type, out hasDataContract, false); 375 } 376 GetStableName(Type type, out bool hasDataContract, bool supportCollectionDataContract)377 public static XmlQualifiedName GetStableName(Type type, out bool hasDataContract, bool supportCollectionDataContract) 378 { 379 DataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(type); 380 if (primitiveContract != null) 381 { 382 hasDataContract = false; 383 return primitiveContract.StableName; 384 } 385 386 string name = null, ns = null; 387 if (type.IsArray) 388 { 389 hasDataContract = false; 390 Type elementType = type; 391 string arrayOfPrefix = ""; 392 while (elementType.IsArray) 393 { 394 arrayOfPrefix += "ArrayOf"; 395 elementType = elementType.GetElementType(); 396 if (elementType == Globals.TypeOfByteArray) 397 break; 398 } 399 XmlQualifiedName elementStableName = GetStableName(elementType, supportCollectionDataContract); 400 name = arrayOfPrefix + elementStableName.Name; 401 ns = (elementStableName.Namespace == Globals.SchemaNamespace) ? Globals.SerializationNamespace : elementStableName.Namespace; 402 } 403 else if (type.IsSerializable && !type.IsEnum) 404 { 405 if (type.IsDefined(Globals.TypeOfDataContractAttribute, false)) 406 throw new Exception("TypeTwoWaySerializable" + type.FullName); 407 hasDataContract = false; 408 name = GetDefaultStableLocalName(type); 409 ns = GetDefaultStableNamespace(type); 410 } 411 else 412 { 413 object[] dataContractAttributes = type.GetCustomAttributes(Globals.TypeOfDataContractAttribute, false); 414 if (dataContractAttributes != null && dataContractAttributes.Length > 0) 415 { 416 DataContractAttribute dataContractAttribute = (DataContractAttribute)dataContractAttributes[0]; 417 hasDataContract = true; 418 if (dataContractAttribute.Name != null) 419 { 420 name = dataContractAttribute.Name; 421 if (name.Length == 0) 422 throw new Exception("InvalidDataContractName" + type.FullName); 423 } 424 else 425 name = GetDefaultStableLocalName(type); 426 427 if (dataContractAttribute.Namespace != null) 428 { 429 ns = dataContractAttribute.Namespace; 430 } 431 else 432 { 433 string clrNs = type.Namespace; 434 if (clrNs == null) 435 clrNs = String.Empty; 436 ns = GetGlobalContractNamespace(clrNs, type.Module); 437 if (ns == null) 438 ns = GetGlobalContractNamespace(clrNs, type.Assembly); 439 440 if (ns == null) 441 ns = GetDefaultStableNamespace(type); 442 } 443 Uri uri; 444 if (Uri.TryCreate(ns, UriKind.RelativeOrAbsolute, out uri)) 445 { 446 string normalizedNs = uri.ToString(); 447 448 if (normalizedNs == Globals.SerializationNamespace || normalizedNs == Globals.SchemaNamespace || normalizedNs == Globals.SchemaInstanceNamespace) 449 throw new Exception("InvalidNamespace" + type.FullName + " :" + Globals.SerializationNamespace + " :" + Globals.SchemaNamespace + " :" + Globals.SchemaInstanceNamespace); 450 } 451 } 452 else if (type.IsEnum) 453 { 454 hasDataContract = false; 455 name = GetDefaultStableLocalName(type); 456 ns = GetDefaultStableNamespace(type); 457 } 458 else if (type.GetInterface("System.Xml.Serialization.IXmlSerializable") != null) 459 { 460 hasDataContract = false; 461 name = GetDefaultStableLocalName(type); 462 ns = GetDefaultStableNamespace(type); 463 } 464 else 465 { 466 object[] collectionDataContractAttributes = type.GetCustomAttributes(Globals.TypeOfCollectionDataContractAttribute, false); 467 if (supportCollectionDataContract && collectionDataContractAttributes != null && collectionDataContractAttributes.Length > 0) 468 { 469 CollectionDataContractAttribute collectionDataContractAttribute = (CollectionDataContractAttribute)collectionDataContractAttributes[0]; 470 hasDataContract = true; 471 if (collectionDataContractAttribute.Name != null) 472 { 473 name = collectionDataContractAttribute.Name; 474 if (name.Length == 0) 475 throw new Exception("InvalidDataContractName" + type.FullName); 476 } 477 else 478 name = GetDefaultStableLocalName(type); 479 480 if (collectionDataContractAttribute.Namespace != null) 481 { 482 ns = collectionDataContractAttribute.Namespace; 483 } 484 else 485 { 486 string clrNs = type.Namespace; 487 if (clrNs == null) 488 clrNs = String.Empty; 489 ns = GetGlobalContractNamespace(clrNs, type.Module); 490 if (ns == null) 491 ns = GetGlobalContractNamespace(clrNs, type.Assembly); 492 493 if (ns == null) 494 ns = GetDefaultStableNamespace(type); 495 } 496 Uri uri; 497 if (Uri.TryCreate(ns, UriKind.RelativeOrAbsolute, out uri)) 498 { 499 string normalizedNs = uri.ToString(); 500 501 if (normalizedNs == Globals.SerializationNamespace || normalizedNs == Globals.SchemaNamespace || normalizedNs == Globals.SchemaInstanceNamespace) 502 throw new Exception("InvalidNamespace" + type.FullName + " :" + Globals.SerializationNamespace + " :" + Globals.SchemaNamespace + " :" + Globals.SchemaInstanceNamespace); 503 } 504 } 505 else 506 { 507 hasDataContract = false; 508 name = GetDefaultStableLocalName(type); 509 ns = GetDefaultStableNamespace(type); 510 } 511 } 512 } 513 return new XmlQualifiedName(name, ns); 514 } 515 GetDefaultStableLocalName(Type type)516 static string GetDefaultStableLocalName(Type type) 517 { 518 if (type.DeclaringType == null) 519 return type.Name; 520 int nsLen = (type.Namespace == null) ? 0 : type.Namespace.Length; 521 if (nsLen > 0) 522 nsLen++; 523 return type.FullName.Substring(nsLen).Replace('+', '.'); 524 } 525 GetDefaultStableNamespace(Type type)526 static string GetDefaultStableNamespace(Type type) 527 { 528 return GetDefaultStableNamespace(type.Namespace); 529 } 530 GetDefaultStableNamespace(string clrNs)531 public static string GetDefaultStableNamespace(string clrNs) 532 { 533 if (clrNs == null) clrNs = String.Empty; 534 return Globals.DefaultNamespace + clrNs.Replace('.', '/'); 535 } 536 GetGlobalContractNamespace(string clrNs, ICustomAttributeProvider customAttribuetProvider)537 static string GetGlobalContractNamespace(string clrNs, ICustomAttributeProvider customAttribuetProvider) 538 { 539 object[] nsAttributes = customAttribuetProvider.GetCustomAttributes(typeof(ContractNamespaceAttribute), false); 540 string dataContractNs = null; 541 for (int i = 0; i < nsAttributes.Length; i++) 542 { 543 ContractNamespaceAttribute nsAttribute = (ContractNamespaceAttribute)nsAttributes[i]; 544 string clrNsInAttribute = nsAttribute.ClrNamespace; 545 if (clrNsInAttribute == null) 546 clrNsInAttribute = String.Empty; 547 if (clrNsInAttribute == clrNs) 548 { 549 if (nsAttribute.ContractNamespace == null) 550 throw new Exception("InvalidGlobalContractNamespace:" + clrNs); 551 if (dataContractNs != null) 552 throw new Exception("ContractNamespaceAlreadySet:" + dataContractNs + " :: " + nsAttribute.ContractNamespace + " :: " + clrNs); 553 dataContractNs = nsAttribute.ContractNamespace; 554 } 555 } 556 return dataContractNs; 557 } 558 GetIsReferenceValue()559 bool GetIsReferenceValue() 560 { 561 Type type = this.UnderlyingType; 562 { 563 object[] dataContractAttributes = type.GetCustomAttributes(Globals.TypeOfDataContractAttribute, false); 564 object[] serAttributes = type.GetCustomAttributes(Globals.TypeOfSerializableAttribute, false); 565 566 if (dataContractAttributes != null && dataContractAttributes.Length > 0) 567 { 568 DataContractAttribute dataContractAttribute = (DataContractAttribute)dataContractAttributes[0]; 569 if (!dataContractAttribute.IsReference && this is ClassDataContract && ((ClassDataContract)this).BaseContract != null) 570 { 571 return ((ClassDataContract)this).BaseContract.IsReference; 572 } 573 else 574 { 575 return dataContractAttribute.IsReference; 576 } 577 } 578 else if (serAttributes != null && serAttributes.Length > 0) 579 { 580 if (this is ClassDataContract && ((ClassDataContract)this).BaseContract != null) 581 { 582 return ((ClassDataContract)this).BaseContract.IsReference; 583 } 584 else 585 { 586 return false; 587 } 588 } 589 } 590 { 591 object[] collectionDataContractAttributes = type.GetCustomAttributes(Globals.TypeOfCollectionDataContractAttribute, false); 592 if (collectionDataContractAttributes != null && collectionDataContractAttributes.Length > 0) 593 { 594 CollectionDataContractAttribute collectionDataContractAttribute = (CollectionDataContractAttribute)collectionDataContractAttributes[0]; 595 return collectionDataContractAttribute.IsReference; 596 } 597 } 598 return false; 599 } 600 DataContract()601 public DataContract() 602 { 603 } 604 DataContract(bool supportCollectionDataContract)605 public DataContract(bool supportCollectionDataContract) 606 { 607 this.supportCollectionDataContract = supportCollectionDataContract; 608 } 609 DataContract(Type type)610 public DataContract(Type type) 611 { 612 underlyingType = type; 613 isValueType = type.IsValueType; 614 } 615 DataContract(Type type, bool supportCollectionDataContract)616 public DataContract(Type type, bool supportCollectionDataContract) 617 : this(type) 618 { 619 this.supportCollectionDataContract = supportCollectionDataContract; 620 } 621 622 public Type UnderlyingType 623 { 624 get { return underlyingType; } 625 } 626 627 public virtual string TopLevelElementName 628 { 629 get { return StableName.Name; } 630 } 631 632 public virtual string TopLevelElementNamespace 633 { 634 get { return StableName.Namespace; } 635 } 636 637 public bool IsValueType 638 { 639 get { return isValueType; } 640 set { isValueType = value; } 641 } 642 643 public XmlQualifiedName StableName 644 { 645 get { return stableName; } 646 set { stableName = value; } 647 } 648 649 public virtual bool IsISerializable 650 { 651 get { return false; } 652 set { throw new InvalidOperationException("RequiresClassDataContractToSetIsISerializable"); } 653 } 654 655 public bool IsReference 656 { 657 get { return GetIsReferenceValue(); } 658 } 659 IsAlpha(char ch)660 static bool IsAlpha(char ch) 661 { 662 return (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z'); 663 } 664 IsDigit(char ch)665 static bool IsDigit(char ch) 666 { 667 return (ch >= '0' && ch <= '9'); 668 } 669 IsAsciiLocalName(string localName)670 static bool IsAsciiLocalName(string localName) 671 { 672 if (String.IsNullOrEmpty(localName) || localName.Length == 0) 673 return false; 674 if (!IsAlpha(localName[0])) 675 return false; 676 for (int i = 1; i < localName.Length; i++) 677 { 678 char ch = localName[i]; 679 if (!IsAlpha(ch) && !IsDigit(ch)) 680 return false; 681 } 682 return true; 683 } 684 EncodeLocalName(string localName)685 static internal string EncodeLocalName(string localName) 686 { 687 if (IsAsciiLocalName(localName)) 688 return localName; 689 690 if (IsValidNCName(localName)) 691 return localName; 692 693 return XmlConvert.EncodeLocalName(localName); 694 } 695 IsValidNCName(string name)696 internal static bool IsValidNCName(string name) 697 { 698 try 699 { 700 XmlConvert.VerifyNCName(name); 701 return true; 702 } 703 catch (XmlException) 704 { 705 return false; 706 } 707 } 708 Equals(object other)709 public override bool Equals(object other) 710 { 711 if ((object)this == other) 712 return true; 713 DataContract dataContract = other as DataContract; 714 if (dataContract != null) 715 { 716 return (StableName.Name == dataContract.StableName.Name && StableName.Namespace == dataContract.StableName.Namespace && IsValueType == dataContract.IsValueType && IsReference == dataContract.IsReference); 717 } 718 return false; 719 } 720 GetHashCode()721 public override int GetHashCode() 722 { 723 return base.GetHashCode(); 724 } 725 } 726 727 public class ClassDataContract : DataContract 728 { 729 ClassDataContract baseContract; 730 List<DataMember> members; 731 string[][] memberNames; 732 bool isISerializable; 733 bool hasDataContract; 734 ClassDataContract(Type type)735 public ClassDataContract(Type type) 736 : this(type, false) 737 { 738 } 739 ClassDataContract(Type type, bool supportCollectionDataContract)740 public ClassDataContract(Type type, bool supportCollectionDataContract) 741 : base(type, supportCollectionDataContract) 742 { 743 Init(type); 744 } 745 746 Init(Type type)747 void Init(Type type) 748 { 749 this.StableName = DataContract.GetStableName(type, out hasDataContract, supportCollectionDataContract); 750 Type baseType = type.BaseType; 751 isISerializable = (Globals.TypeOfISerializable.IsAssignableFrom(type)); 752 if (isISerializable) 753 { 754 if (hasDataContract) 755 throw new Exception("DataContractTypeCannotBeISerializable: " + type.FullName); 756 if (!Globals.TypeOfISerializable.IsAssignableFrom(baseType)) 757 { 758 while (baseType != null) 759 { 760 if (baseType.IsDefined(Globals.TypeOfDataContractAttribute, false)) 761 throw new Exception("ISerializableCannotInheritFromDataContract:" + type.FullName + "::" + baseType.FullName); 762 baseType = baseType.BaseType; 763 } 764 } 765 } 766 if (baseType != null && baseType != Globals.TypeOfObject && baseType != Globals.TypeOfValueType) 767 this.BaseContract = (ClassDataContract)DataContract.GetDataContract(baseType, supportCollectionDataContract); 768 else 769 this.BaseContract = null; 770 } 771 ImportDataMembers()772 void ImportDataMembers() 773 { 774 Type type = this.UnderlyingType; 775 members = new List<DataMember>(); 776 Dictionary<string, DataMember> memberNamesTable = new Dictionary<string, DataMember>(); 777 MemberInfo[] memberInfos = type.GetMembers(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 778 779 for (int i = 0; i < memberInfos.Length; i++) 780 { 781 MemberInfo member = memberInfos[i]; 782 if (hasDataContract) 783 { 784 object[] memberAttributes = member.GetCustomAttributes(typeof(System.Runtime.Serialization.DataMemberAttribute), false); 785 if (memberAttributes != null && memberAttributes.Length > 0) 786 { 787 if (memberAttributes.Length > 1) 788 throw new Exception("TooManyDataMembers:" + member.DeclaringType.FullName + "::" + member.Name); 789 if (member.MemberType == MemberTypes.Property) 790 { 791 PropertyInfo property = (PropertyInfo)member; 792 MethodInfo getMethod = property.GetGetMethod(true); 793 if (getMethod != null && IsMethodOverriding(getMethod)) 794 continue; 795 MethodInfo setMethod = property.GetSetMethod(true); 796 if (setMethod != null && IsMethodOverriding(setMethod)) 797 continue; 798 if (getMethod == null) 799 throw new Exception(" NoGetMethodForProperty : " + property.DeclaringType + " ::" + property.Name); 800 if (setMethod == null) 801 throw new Exception("NoSetMethodForProperty : " + property.DeclaringType + " :: " + property.Name); 802 if (getMethod.GetParameters().Length > 0) 803 throw new Exception("IndexedPropertyCannotBeSerialized :" + property.DeclaringType + " :: " + property.Name); 804 } 805 else if (member.MemberType != MemberTypes.Field) 806 throw new Exception("InvalidMember : " + type.FullName + " :: " + member.Name + " :: " + typeof(System.Runtime.Serialization.DataMemberAttribute).FullName); 807 808 DataMember memberContract = new DataMember(member); 809 System.Runtime.Serialization.DataMemberAttribute memberAttribute = (System.Runtime.Serialization.DataMemberAttribute)memberAttributes[0]; 810 if (memberAttribute.Name == null) 811 memberContract.Name = member.Name; 812 else 813 memberContract.Name = memberAttribute.Name; 814 memberContract.Order = memberAttribute.Order; 815 memberContract.IsRequired = memberAttribute.IsRequired; 816 CheckAndAddMember(members, memberContract, memberNamesTable); 817 } 818 } 819 else 820 { 821 FieldInfo field = member as FieldInfo; 822 if (field != null && !field.IsNotSerialized) 823 { 824 DataMember memberContract = new DataMember(member); 825 memberContract.Name = member.Name; 826 object[] optionalFields = field.GetCustomAttributes(Globals.TypeOfOptionalFieldAttribute, false); 827 if (optionalFields == null || optionalFields.Length == 0) 828 memberContract.Order = Globals.DefaultVersion; 829 else 830 { 831 memberContract.IsRequired = Globals.DefaultIsRequired; 832 } 833 CheckAndAddMember(members, memberContract, memberNamesTable); 834 } 835 } 836 } 837 if (members.Count > 1) 838 members.Sort(DataMemberComparer.Singleton); 839 } 840 CheckAndAddMember(List<DataMember> members, DataMember memberContract, Dictionary<string, DataMember> memberNamesTable)841 public static void CheckAndAddMember(List<DataMember> members, DataMember memberContract, Dictionary<string, DataMember> memberNamesTable) 842 { 843 DataMember existingMemberContract; 844 if (memberNamesTable.TryGetValue(memberContract.Name, out existingMemberContract)) 845 throw new Exception("DupMemberName :" + existingMemberContract.MemberInfo.Name + " :: " + memberContract.MemberInfo.Name + " :: " + memberContract.MemberInfo.DeclaringType.FullName + " :: " + memberContract.Name); 846 memberNamesTable.Add(memberContract.Name, memberContract); 847 members.Add(memberContract); 848 } 849 IsMethodOverriding(MethodInfo method)850 static bool IsMethodOverriding(MethodInfo method) 851 { 852 return method.IsVirtual && ((method.Attributes & MethodAttributes.NewSlot) == 0); 853 } 854 855 public ClassDataContract BaseContract 856 { 857 get { return baseContract; } 858 set { baseContract = value; } 859 } 860 861 public string[][] MemberNames 862 { 863 get 864 { 865 if (memberNames == null) 866 { 867 lock (this) 868 { 869 if (memberNames == null && Members != null) 870 { 871 if (baseContract == null) 872 memberNames = new string[1][]; 873 else 874 { 875 int baseTypesCount = baseContract.MemberNames.Length; 876 memberNames = new string[baseTypesCount + 1][]; 877 Array.Copy(baseContract.MemberNames, 0, memberNames, 0, baseTypesCount); 878 } 879 string[] declaredMemberNames = new string[Members.Count]; 880 for (int i = 0; i < Members.Count; i++) 881 declaredMemberNames[i] = Members[i].Name; 882 memberNames[memberNames.Length - 1] = declaredMemberNames; 883 } 884 } 885 } 886 return memberNames; 887 } 888 } 889 890 public List<DataMember> Members 891 { 892 get 893 { 894 if (members == null && UnderlyingType != null && !IsISerializable) 895 { 896 lock (this) 897 { 898 if (members == null) 899 { 900 ImportDataMembers(); 901 } 902 } 903 } 904 return members; 905 } 906 set { members = value; } 907 } 908 Equals(object other)909 public override bool Equals(object other) 910 { 911 if ((object)this == other) 912 return true; 913 914 if (base.Equals(other)) 915 { 916 ClassDataContract dataContract = other as ClassDataContract; 917 if (dataContract != null) 918 { 919 if (IsISerializable) 920 { 921 if (!dataContract.IsISerializable) 922 return false; 923 } 924 else 925 { 926 if (dataContract.IsISerializable) 927 return false; 928 929 if (Members == null) 930 { 931 if (dataContract.Members != null) 932 return false; 933 } 934 else if (dataContract.Members == null) 935 return false; 936 else 937 { 938 if (Members.Count != dataContract.Members.Count) 939 return false; 940 941 for (int i = 0; i < Members.Count; i++) 942 { 943 if (!Members[i].Equals(dataContract.Members[i])) 944 return false; 945 } 946 } 947 } 948 949 if (BaseContract == null) 950 return (dataContract.BaseContract == null); 951 else if (dataContract.BaseContract == null) 952 return false; 953 else 954 return BaseContract.StableName.Equals(dataContract.BaseContract.StableName); 955 } 956 } 957 return false; 958 } 959 GetHashCode()960 public override int GetHashCode() 961 { 962 return base.GetHashCode(); 963 } 964 965 public class DataMemberComparer : IComparer<DataMember> 966 { Compare(DataMember x, DataMember y)967 public int Compare(DataMember x, DataMember y) 968 { 969 if (x.Order < y.Order) 970 return -1; 971 if (x.Order > y.Order) 972 return 1; 973 return String.Compare(x.Name, y.Name, StringComparison.InvariantCulture); 974 } 975 Equals(DataMember x, DataMember y)976 public bool Equals(DataMember x, DataMember y) 977 { 978 return x == y; 979 } 980 GetHashCode(DataMember x)981 public int GetHashCode(DataMember x) 982 { 983 return ((object)x).GetHashCode(); 984 } 985 public static DataMemberComparer Singleton = new DataMemberComparer(); 986 } 987 988 public class DataMemberOrderComparer : IComparer<DataMember> 989 { Compare(DataMember x, DataMember y)990 public int Compare(DataMember x, DataMember y) 991 { 992 return x.Order - y.Order; 993 } 994 Equals(DataMember x, DataMember y)995 public bool Equals(DataMember x, DataMember y) 996 { 997 return x.Order == y.Order; 998 } 999 GetHashCode(DataMember x)1000 public int GetHashCode(DataMember x) 1001 { 1002 return ((object)x).GetHashCode(); 1003 } 1004 public static DataMemberOrderComparer Singleton = new DataMemberOrderComparer(); 1005 } 1006 1007 } 1008 1009 public class DataMember 1010 { 1011 DataContract memberTypeContract; 1012 string name; 1013 int order; 1014 bool isRequired; 1015 bool isNullable; 1016 MemberInfo memberInfo; 1017 protected internal bool supportCollectionDataContract; 1018 DataMember()1019 public DataMember() 1020 { 1021 } 1022 DataMember(MemberInfo memberInfo)1023 public DataMember(MemberInfo memberInfo) 1024 { 1025 this.memberInfo = memberInfo; 1026 } 1027 1028 public MemberInfo MemberInfo 1029 { 1030 get { return memberInfo; } 1031 } 1032 1033 public string Name 1034 { 1035 get { return name; } 1036 set { name = value; } 1037 } 1038 1039 public int Order 1040 { 1041 get { return order; } 1042 set { order = value; } 1043 } 1044 1045 internal bool IsNullable 1046 { 1047 get { return isNullable; } 1048 set { isNullable = value; } 1049 } 1050 1051 public bool IsRequired 1052 { 1053 get { return isRequired; } 1054 set { isRequired = value; } 1055 } 1056 GetMemberValue(object obj)1057 public object GetMemberValue(object obj) 1058 { 1059 FieldInfo field = MemberInfo as FieldInfo; 1060 1061 if (field != null) 1062 return ((FieldInfo)MemberInfo).GetValue(obj); 1063 1064 return ((PropertyInfo)MemberInfo).GetValue(obj, null); 1065 } 1066 1067 public Type MemberType 1068 { 1069 get 1070 { 1071 FieldInfo field = MemberInfo as FieldInfo; 1072 if (field != null) 1073 return field.FieldType; 1074 return ((PropertyInfo)MemberInfo).PropertyType; 1075 } 1076 } 1077 1078 public DataContract MemberTypeContract 1079 { 1080 get 1081 { 1082 if (memberTypeContract == null) 1083 { 1084 if (MemberInfo != null) 1085 { 1086 lock (this) 1087 { 1088 if (memberTypeContract == null) 1089 { 1090 memberTypeContract = DataContract.GetDataContract(MemberType, supportCollectionDataContract); 1091 } 1092 } 1093 } 1094 } 1095 return memberTypeContract; 1096 } 1097 set 1098 { 1099 memberTypeContract = value; 1100 } 1101 } 1102 Equals(object other)1103 public override bool Equals(object other) 1104 { 1105 if ((object)this == other) 1106 return true; 1107 1108 DataMember dataMember = other as DataMember; 1109 if (dataMember != null) 1110 { 1111 return (Name == dataMember.Name 1112 && IsNullable == dataMember.IsNullable 1113 && IsRequired == dataMember.IsRequired 1114 && MemberTypeContract.StableName.Equals(dataMember.MemberTypeContract.StableName)); 1115 } 1116 return false; 1117 } 1118 operator <(DataMember dm1, DataMember dm2)1119 public static bool operator <(DataMember dm1, DataMember dm2) 1120 { 1121 if (dm1.Order != dm2.Order) 1122 return dm1.Order < dm2.Order; 1123 else 1124 return ((string.Compare(dm1.Name, dm2.Name) < 0) ? true : false); 1125 } 1126 operator >(DataMember dm1, DataMember dm2)1127 public static bool operator >(DataMember dm1, DataMember dm2) 1128 { 1129 if (dm1.Order != dm2.Order) 1130 return dm1.Order > dm2.Order; 1131 else 1132 return ((string.Compare(dm1.Name, dm2.Name) > 0) ? true : false); 1133 } 1134 NameOrderEquals(object other)1135 public bool NameOrderEquals(object other) 1136 { 1137 if ((object)this == other) 1138 return true; 1139 DataMember dataMember = other as DataMember; 1140 if (dataMember != null) 1141 { 1142 return (Name == dataMember.Name 1143 && Order == dataMember.Order 1144 && MemberTypeContract.StableName.Equals(dataMember.MemberTypeContract.StableName)); 1145 } 1146 return false; 1147 1148 } 1149 GetHashCode()1150 public override int GetHashCode() 1151 { 1152 return base.GetHashCode(); 1153 } 1154 } 1155 1156 public class PrimitiveDataContract : DataContract 1157 { 1158 static Dictionary<Type, PrimitiveDataContract> typeToContract = new Dictionary<Type, PrimitiveDataContract>(); 1159 static Dictionary<XmlQualifiedName, PrimitiveDataContract> nameToContract = new Dictionary<XmlQualifiedName, PrimitiveDataContract>(); 1160 static PrimitiveDataContract objectContract = new PrimitiveDataContract(typeof(object)); 1161 PrimitiveDataContract()1162 static PrimitiveDataContract() 1163 { 1164 Add(new PrimitiveDataContract(typeof(char))); 1165 Add(new PrimitiveDataContract(typeof(bool))); 1166 Add(new PrimitiveDataContract(typeof(sbyte))); 1167 Add(new PrimitiveDataContract(typeof(byte))); 1168 Add(new PrimitiveDataContract(typeof(short))); 1169 Add(new PrimitiveDataContract(typeof(ushort))); 1170 Add(new PrimitiveDataContract(typeof(int))); 1171 Add(new PrimitiveDataContract(typeof(uint))); 1172 Add(new PrimitiveDataContract(typeof(long))); 1173 Add(new PrimitiveDataContract(typeof(ulong))); 1174 Add(new PrimitiveDataContract(typeof(float))); 1175 Add(new PrimitiveDataContract(typeof(double))); 1176 Add(new PrimitiveDataContract(typeof(decimal))); 1177 Add(new PrimitiveDataContract(typeof(DateTime))); 1178 Add(new PrimitiveDataContract(typeof(string))); 1179 Add(new PrimitiveDataContract(typeof(byte[]))); 1180 Add(new PrimitiveDataContract(typeof(TimeSpan))); 1181 Add(new PrimitiveDataContract(typeof(Guid))); 1182 Add(new PrimitiveDataContract(typeof(Uri))); 1183 Add(objectContract); 1184 } Add(PrimitiveDataContract primitiveContract)1185 static public void Add(PrimitiveDataContract primitiveContract) 1186 { 1187 typeToContract.Add(primitiveContract.UnderlyingType, primitiveContract); 1188 nameToContract.Add(primitiveContract.StableName, primitiveContract); 1189 } 1190 GetPrimitiveDataContract(Type type)1191 static public PrimitiveDataContract GetPrimitiveDataContract(Type type) 1192 { 1193 PrimitiveDataContract retVal = null; 1194 if (type.IsInterface) 1195 retVal = objectContract; 1196 else 1197 typeToContract.TryGetValue(type, out retVal); 1198 return retVal; 1199 } 1200 GetPrimitiveDataContract(string name, string ns)1201 static public PrimitiveDataContract GetPrimitiveDataContract(string name, string ns) 1202 { 1203 PrimitiveDataContract retVal = null; 1204 nameToContract.TryGetValue(new XmlQualifiedName(name, ns), out retVal); 1205 return retVal; 1206 } 1207 PrimitiveDataContract(Type type)1208 PrimitiveDataContract(Type type) : base(type) 1209 { 1210 string name = null; 1211 string ns = Globals.SchemaNamespace; 1212 switch (Type.GetTypeCode(type)) 1213 { 1214 case TypeCode.Char: 1215 name = "char"; 1216 ns = Globals.SerializationNamespace; 1217 break; 1218 case TypeCode.Boolean: 1219 name = "boolean"; 1220 break; 1221 case TypeCode.SByte: 1222 name = "byte"; 1223 break; 1224 case TypeCode.Byte: 1225 name = "unsignedByte"; 1226 break; 1227 case TypeCode.Int16: 1228 name = "short"; 1229 break; 1230 case TypeCode.UInt16: 1231 name = "unsignedShort"; 1232 break; 1233 case TypeCode.Int32: 1234 name = "int"; 1235 break; 1236 case TypeCode.UInt32: 1237 name = "unsignedInt"; 1238 break; 1239 case TypeCode.Int64: 1240 name = "long"; 1241 break; 1242 case TypeCode.UInt64: 1243 name = "unsignedLong"; 1244 break; 1245 case TypeCode.Single: 1246 name = "float"; 1247 break; 1248 case TypeCode.Double: 1249 name = "double"; 1250 break; 1251 case TypeCode.Decimal: 1252 name = "decimal"; 1253 break; 1254 case TypeCode.DateTime: 1255 name = "dateTime"; 1256 break; 1257 case TypeCode.String: 1258 name = "string"; 1259 break; 1260 default: 1261 if (type == Globals.TypeOfByteArray) 1262 { 1263 name = "base64Binary"; 1264 ns = Globals.SerializationNamespace; 1265 } 1266 else if (type == Globals.TypeOfObject) 1267 { 1268 name = "anyType"; 1269 } 1270 else if (type == Globals.TypeOfTimeSpan) 1271 { 1272 name = "duration"; 1273 } 1274 else if (type == Globals.TypeOfGuid) 1275 { 1276 name = "guid"; 1277 } 1278 else if (type == Globals.TypeOfUri) 1279 { 1280 name = "anyURI"; 1281 } 1282 else 1283 throw new Exception(string.Format("{0} is an invalidPrimitiveType", type.FullName)); 1284 break; 1285 } 1286 StableName = new XmlQualifiedName(name, ns); 1287 } 1288 1289 public override string TopLevelElementNamespace 1290 { 1291 get { return Globals.SerializationNamespace; } 1292 } 1293 } 1294 1295 public class ArrayDataContract : DataContract 1296 { 1297 DataContract itemContract; 1298 int rank; 1299 ArrayDataContract(Type type, bool supportCollectionDataContract)1300 public ArrayDataContract(Type type, bool supportCollectionDataContract) 1301 : base(type, supportCollectionDataContract) 1302 { 1303 rank = type.GetArrayRank(); 1304 StableName = DataContract.GetStableName(type, supportCollectionDataContract); 1305 } 1306 ArrayDataContract(Type type)1307 public ArrayDataContract(Type type) 1308 : this(type, false) 1309 { 1310 } 1311 1312 public DataContract ItemContract 1313 { 1314 get 1315 { 1316 if (itemContract == null && UnderlyingType != null) 1317 { 1318 itemContract = DataContract.GetDataContract(UnderlyingType.GetElementType(), supportCollectionDataContract); 1319 } 1320 return itemContract; 1321 } 1322 set 1323 { 1324 itemContract = value; 1325 } 1326 } 1327 Equals(object other)1328 public override bool Equals(object other) 1329 { 1330 if ((object)this == other) 1331 return true; 1332 1333 if (base.Equals(other)) 1334 { 1335 ArrayDataContract dataContract = other as ArrayDataContract; 1336 if (dataContract != null) 1337 { 1338 return ItemContract.Equals(dataContract.itemContract); 1339 } 1340 } 1341 return false; 1342 } 1343 GetHashCode()1344 public override int GetHashCode() 1345 { 1346 return base.GetHashCode(); 1347 } 1348 } 1349 1350 public class EnumDataContract : DataContract 1351 { 1352 PrimitiveDataContract baseContract; 1353 List<DataMember> members; 1354 List<long> values; 1355 bool isULong; 1356 bool isFlags; 1357 bool hasDataContract; 1358 EnumDataContract()1359 public EnumDataContract() 1360 { 1361 IsValueType = true; 1362 } 1363 EnumDataContract(Type type)1364 public EnumDataContract(Type type) : base(type) 1365 { 1366 StableName = DataContract.GetStableName(type, out hasDataContract); 1367 Type baseType = Enum.GetUnderlyingType(type); 1368 baseContract = PrimitiveDataContract.GetPrimitiveDataContract(baseType); 1369 isULong = (baseType == Globals.TypeOfULong); 1370 IsFlags = type.IsDefined(Globals.TypeOfFlagsAttribute, false); 1371 } 1372 1373 public PrimitiveDataContract BaseContract 1374 { 1375 get 1376 { 1377 return baseContract; 1378 } 1379 set 1380 { 1381 baseContract = value; 1382 isULong = (baseContract.UnderlyingType == Globals.TypeOfULong); 1383 } 1384 } 1385 ImportDataMembers()1386 void ImportDataMembers() 1387 { 1388 Type type = this.UnderlyingType; 1389 FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); 1390 members = new List<DataMember>(fields.Length); 1391 Dictionary<string, DataMember> memberNamesTable = new Dictionary<string, DataMember>(); 1392 values = new List<long>(fields.Length); 1393 1394 for (int i = 0; i < fields.Length; i++) 1395 { 1396 FieldInfo field = fields[i]; 1397 bool dataMemberValid = false; 1398 object[] memberAttributes = field.GetCustomAttributes(Globals.TypeOfDataMemberAttribute, false); 1399 if (hasDataContract) 1400 { 1401 if (memberAttributes != null && memberAttributes.Length > 0) 1402 { 1403 if (memberAttributes.Length > 1) 1404 throw new Exception("TooManyDataMembers :" + field.DeclaringType.FullName + " :: " + field.Name); 1405 DataMemberAttribute memberAttribute = (DataMemberAttribute)memberAttributes[0]; 1406 DataMember memberContract = new DataMember(field); 1407 if (memberAttribute.Name == null || memberAttribute.Name.Length == 0) 1408 memberContract.Name = field.Name; 1409 else 1410 memberContract.Name = memberAttribute.Name; 1411 ClassDataContract.CheckAndAddMember(members, memberContract, memberNamesTable); 1412 dataMemberValid = true; 1413 } 1414 } 1415 else 1416 { 1417 if (!field.IsNotSerialized) 1418 { 1419 DataMember memberContract = new DataMember(field); 1420 memberContract.Name = field.Name; 1421 ClassDataContract.CheckAndAddMember(members, memberContract, memberNamesTable); 1422 dataMemberValid = true; 1423 } 1424 } 1425 1426 if (dataMemberValid) 1427 { 1428 object enumValue = field.GetValue(null); 1429 if (isULong) 1430 values.Add((long)((IConvertible)enumValue).ToUInt64(null)); 1431 else 1432 values.Add(((IConvertible)enumValue).ToInt64(null)); 1433 } 1434 } 1435 } 1436 1437 public List<DataMember> Members 1438 { 1439 get 1440 { 1441 if (members == null && UnderlyingType != null) 1442 { 1443 lock (this) 1444 { 1445 if (members == null) 1446 { 1447 ImportDataMembers(); 1448 } 1449 } 1450 } 1451 return members; 1452 } 1453 set { members = value; } 1454 } 1455 1456 public List<long> Values 1457 { 1458 get 1459 { 1460 if (values == null && UnderlyingType != null) 1461 { 1462 lock (this) 1463 { 1464 if (values == null) 1465 { 1466 ImportDataMembers(); 1467 } 1468 } 1469 } 1470 return values; 1471 } 1472 set { values = value; } 1473 } 1474 1475 public bool IsFlags 1476 { 1477 get { return isFlags; } 1478 set { isFlags = value; } 1479 } 1480 Equals(object other)1481 public override bool Equals(object other) 1482 { 1483 if ((object)this == other) 1484 return true; 1485 1486 if (base.Equals(other)) 1487 { 1488 EnumDataContract dataContract = other as EnumDataContract; 1489 if (dataContract != null) 1490 { 1491 if (IsFlags != dataContract.IsFlags) 1492 return false; 1493 1494 if (Members.Count != dataContract.Members.Count || Values.Count != dataContract.Values.Count) 1495 return false; 1496 1497 for (int i = 0; i < Members.Count; i++) 1498 { 1499 if (Values[i] != dataContract.Values[i] || Members[i].Name != dataContract.Members[i].Name) 1500 return false; 1501 } 1502 1503 return BaseContract.StableName.Equals(dataContract.BaseContract.StableName); 1504 } 1505 } 1506 return false; 1507 } GetHashCode()1508 public override int GetHashCode() 1509 { 1510 if (members != null) 1511 { 1512 int hash = 0; 1513 foreach (DataMember member in members) 1514 hash += member.Name.GetHashCode(); 1515 hash += base.StableName.GetHashCode(); 1516 return hash; 1517 } 1518 else 1519 { 1520 return base.GetHashCode(); 1521 } 1522 } 1523 } 1524 1525 public enum CollectionKind : byte 1526 { 1527 None, 1528 GenericDictionary, 1529 Dictionary, 1530 GenericList, 1531 GenericCollection, 1532 List, 1533 GenericEnumerable, 1534 Collection, 1535 Enumerable, 1536 Array, 1537 } 1538 1539 [DataContractAttribute(Namespace = "http://schemas.microsoft.com/2003/10/Serialization/Arrays")] 1540 public struct KeyValue<K, V> 1541 { 1542 K key; 1543 V value; 1544 KeyValueSerializationTestTypes.KeyValue1545 internal KeyValue(K key, V value) 1546 { 1547 this.key = key; 1548 this.value = value; 1549 } 1550 1551 [DataMember(IsRequired = true)] 1552 public K Key 1553 { 1554 get { return key; } 1555 set { key = value; } 1556 } 1557 1558 [DataMember(IsRequired = true)] 1559 public V Value 1560 { 1561 get { return value; } 1562 set { this.value = value; } 1563 } 1564 } 1565 1566 public class CollectionDataContract : DataContract 1567 { 1568 public CollectionKind Kind; 1569 public Type ItemType; 1570 public string ItemName; 1571 public String CollectionItemName; 1572 public string KeyName; 1573 public string ValueName; 1574 1575 public bool IsDictionary 1576 { 1577 get { return !String.IsNullOrEmpty(KeyName); } 1578 } 1579 1580 public MethodInfo GetEnumeratorMethod; 1581 public MethodInfo AddMethod; 1582 public ConstructorInfo Constructor; 1583 CollectionDataContract(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor)1584 public CollectionDataContract(Type type, CollectionKind kind, Type itemType, MethodInfo getEnumeratorMethod, MethodInfo addMethod, ConstructorInfo constructor) 1585 : base(type) 1586 { 1587 this.supportCollectionDataContract = true; 1588 StableName = DataContract.GetStableName(type, true); //TODO 1589 Kind = kind; 1590 this.ItemType = itemType; 1591 this.KeyName = null; 1592 this.ValueName = null; 1593 1594 this.GetEnumeratorMethod = getEnumeratorMethod; 1595 this.AddMethod = addMethod; 1596 this.Constructor = constructor; 1597 if (itemType != null) 1598 { 1599 itemContract = DataContract.GetDataContract(itemType, true); 1600 } 1601 Init(type); 1602 } 1603 1604 DataContract itemContract; 1605 public DataContract ItemContract 1606 { 1607 get 1608 { 1609 if (itemContract == null && UnderlyingType != null) 1610 { 1611 itemContract = DataContract.GetDataContract(UnderlyingType.GetElementType(), true); 1612 } 1613 return itemContract; 1614 } 1615 set 1616 { 1617 itemContract = value; 1618 } 1619 } 1620 Init(Type type)1621 void Init(Type type) 1622 { 1623 object[] collectionDataContractAttributes = type.GetCustomAttributes(Globals.TypeOfCollectionDataContractAttribute, false); 1624 CollectionDataContractAttribute collectionContractAttribute = null; 1625 1626 if (collectionDataContractAttributes != null && collectionDataContractAttributes.Length > 0) 1627 { 1628 collectionContractAttribute = (CollectionDataContractAttribute)collectionDataContractAttributes[0]; 1629 } 1630 1631 if (ItemType != null) 1632 { 1633 bool isDictionary = (Kind == CollectionKind.Dictionary || Kind == CollectionKind.GenericDictionary); 1634 string itemName = null, keyName = null, valueName = null; 1635 if (collectionContractAttribute != null) 1636 { 1637 if (!String.IsNullOrEmpty(collectionContractAttribute.ItemName)) 1638 { 1639 itemName = DataContract.EncodeLocalName(collectionContractAttribute.ItemName); 1640 } 1641 if (!String.IsNullOrEmpty(collectionContractAttribute.KeyName)) 1642 { 1643 keyName = DataContract.EncodeLocalName(collectionContractAttribute.KeyName); 1644 } 1645 if (!String.IsNullOrEmpty(collectionContractAttribute.ValueName)) 1646 { 1647 valueName = DataContract.EncodeLocalName(collectionContractAttribute.ValueName); 1648 } 1649 } 1650 1651 this.ItemName = itemName ?? DataContract.GetStableName(DataContract.UnwrapNullableType(ItemType), true).Name; 1652 this.CollectionItemName = this.ItemName; 1653 if (isDictionary) 1654 { 1655 this.KeyName = keyName ?? Globals.KeyLocalName; 1656 this.ValueName = valueName ?? Globals.ValueLocalName; 1657 } 1658 } 1659 } 1660 IsCollectionHelper(Type type, out Type itemType, bool constructorRequired)1661 static bool IsCollectionHelper(Type type, out Type itemType, bool constructorRequired) 1662 { 1663 if (type.IsArray && DataContract.GetDataContract(type, true) == null) 1664 { 1665 itemType = type.GetElementType(); 1666 return true; 1667 } 1668 DataContract dataContract; 1669 return IsCollectionOrTryCreate(type, false /*tryCreate*/, out dataContract, out itemType, constructorRequired); 1670 } 1671 IsCollectionDataContract(Type type)1672 internal static bool IsCollectionDataContract(Type type) 1673 { 1674 return type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false); 1675 } 1676 IsCollectionOrTryCreate(Type type, bool tryCreate, out DataContract dataContract, out Type itemType, bool constructorRequired)1677 public static bool IsCollectionOrTryCreate(Type type, bool tryCreate, out DataContract dataContract, out Type itemType, bool constructorRequired) 1678 { 1679 dataContract = null; 1680 itemType = Globals.TypeOfObject; 1681 MethodInfo addMethod, getEnumeratorMethod; 1682 bool hasCollectionDataContract = IsCollectionDataContract(type); 1683 Type baseType = type.BaseType; 1684 bool isBaseTypeCollection = (baseType != null && baseType != Globals.TypeOfObject 1685 && baseType != Globals.TypeOfValueType && baseType != Globals.TypeOfUri) ? IsCollection(baseType) : false; 1686 1687 if (!Globals.TypeOfIEnumerable.IsAssignableFrom(type) || 1688 IsDC(type) || Globals.TypeOfIXmlSerializable.IsAssignableFrom(type)) 1689 { 1690 return false; 1691 } 1692 1693 if (type.IsInterface) 1694 { 1695 Type interfaceTypeToCheck = type.IsGenericType ? type.GetGenericTypeDefinition() : type; 1696 Type[] knownInterfaces = KnownInterfaces; 1697 for (int i = 0; i < knownInterfaces.Length; i++) 1698 { 1699 if (knownInterfaces[i] == interfaceTypeToCheck) 1700 { 1701 addMethod = null; 1702 if (type.IsGenericType) 1703 { 1704 Type[] genericArgs = type.GetGenericArguments(); 1705 if (interfaceTypeToCheck == Globals.TypeOfIDictionaryGeneric) 1706 { 1707 itemType = Globals.TypeOfKeyValue.MakeGenericType(genericArgs); 1708 addMethod = type.GetMethod(Globals.AddMethodName); 1709 getEnumeratorMethod = Globals.TypeOfIEnumerableGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(genericArgs)).GetMethod(Globals.GetEnumeratorMethodName); 1710 } 1711 else 1712 { 1713 itemType = genericArgs[0]; 1714 getEnumeratorMethod = Globals.TypeOfIEnumerableGeneric.MakeGenericType(itemType).GetMethod(Globals.GetEnumeratorMethodName); 1715 } 1716 } 1717 else 1718 { 1719 if (interfaceTypeToCheck == Globals.TypeOfIDictionary) 1720 { 1721 itemType = typeof(KeyValue<object, object>); 1722 addMethod = type.GetMethod(Globals.AddMethodName); 1723 } 1724 else 1725 { 1726 itemType = Globals.TypeOfObject; 1727 } 1728 getEnumeratorMethod = Globals.TypeOfIEnumerable.GetMethod(Globals.GetEnumeratorMethodName); 1729 } 1730 if (tryCreate) 1731 dataContract = new CollectionDataContract(type, (CollectionKind)(i + 1), itemType, getEnumeratorMethod, addMethod, null/*defaultCtor*/); 1732 return true; 1733 } 1734 } 1735 } 1736 ConstructorInfo defaultCtor = null; 1737 if (!type.IsValueType && constructorRequired) 1738 { 1739 defaultCtor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Globals.EmptyTypeArray, null); 1740 } 1741 1742 Type knownInterfaceType = null; 1743 CollectionKind kind = CollectionKind.None; 1744 bool multipleDefinitions = false; 1745 Type[] interfaceTypes = type.GetInterfaces(); 1746 foreach (Type interfaceType in interfaceTypes) 1747 { 1748 Type interfaceTypeToCheck = interfaceType.IsGenericType ? interfaceType.GetGenericTypeDefinition() : interfaceType; 1749 Type[] knownInterfaces = KnownInterfaces; 1750 for (int i = 0; i < knownInterfaces.Length; i++) 1751 { 1752 if (knownInterfaces[i] == interfaceTypeToCheck) 1753 { 1754 CollectionKind currentKind = (CollectionKind)(i + 1); 1755 if (kind == CollectionKind.None || currentKind < kind) 1756 { 1757 kind = currentKind; 1758 knownInterfaceType = interfaceType; 1759 multipleDefinitions = false; 1760 } 1761 else if ((kind & currentKind) == currentKind) 1762 multipleDefinitions = true; 1763 break; 1764 } 1765 } 1766 } 1767 1768 if (kind == CollectionKind.None) 1769 { 1770 throw new Exception("CollectionTypeIsNotIEnumerable"); 1771 } 1772 1773 if (kind == CollectionKind.Enumerable || kind == CollectionKind.Collection || kind == CollectionKind.GenericEnumerable) 1774 { 1775 if (multipleDefinitions) 1776 knownInterfaceType = Globals.TypeOfIEnumerable; 1777 itemType = knownInterfaceType.IsGenericType ? knownInterfaceType.GetGenericArguments()[0] : Globals.TypeOfObject; 1778 GetCollectionMethods(type, knownInterfaceType, new Type[] { itemType }, 1779 false, 1780 out getEnumeratorMethod, out addMethod); 1781 if (tryCreate) 1782 dataContract = new CollectionDataContract(type, kind, itemType, getEnumeratorMethod, addMethod, defaultCtor); 1783 } 1784 else 1785 { 1786 if (multipleDefinitions) 1787 { 1788 throw new Exception("SR.CollectionTypeHasMultipleDefinitionsOfInterface"); 1789 } 1790 1791 Type[] addMethodTypeArray = null; 1792 switch (kind) 1793 { 1794 case CollectionKind.GenericDictionary: 1795 addMethodTypeArray = knownInterfaceType.GetGenericArguments(); 1796 bool isOpenGeneric = knownInterfaceType.IsGenericTypeDefinition 1797 || (addMethodTypeArray[0].IsGenericParameter && addMethodTypeArray[1].IsGenericParameter); 1798 itemType = isOpenGeneric ? Globals.TypeOfKeyValue : Globals.TypeOfKeyValue.MakeGenericType(addMethodTypeArray); 1799 break; 1800 case CollectionKind.Dictionary: 1801 addMethodTypeArray = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject }; 1802 itemType = Globals.TypeOfKeyValue.MakeGenericType(addMethodTypeArray); 1803 break; 1804 case CollectionKind.GenericList: 1805 case CollectionKind.GenericCollection: 1806 addMethodTypeArray = knownInterfaceType.GetGenericArguments(); 1807 itemType = addMethodTypeArray[0]; 1808 break; 1809 case CollectionKind.List: 1810 itemType = Globals.TypeOfObject; 1811 addMethodTypeArray = new Type[] { itemType }; 1812 break; 1813 } 1814 if (tryCreate) 1815 { 1816 GetCollectionMethods(type, knownInterfaceType, addMethodTypeArray, 1817 true, 1818 out getEnumeratorMethod, out addMethod); 1819 dataContract = new CollectionDataContract(type, kind, itemType, getEnumeratorMethod, addMethod, defaultCtor); 1820 } 1821 } 1822 return true; 1823 } 1824 IsDC(Type type)1825 internal static bool IsDC(Type type) 1826 { 1827 if (type.GetCustomAttributes(Globals.TypeOfDataContractAttribute, false) != null && type.GetCustomAttributes(Globals.TypeOfDataContractAttribute, false).Length > 0) 1828 { 1829 return true; 1830 } 1831 else 1832 { 1833 return false; 1834 } 1835 } 1836 IsCollection(Type type)1837 internal static bool IsCollection(Type type) 1838 { 1839 Type itemType; 1840 return IsCollection(type, out itemType); 1841 } 1842 IsCollection(Type type, out Type itemType)1843 internal static bool IsCollection(Type type, out Type itemType) 1844 { 1845 return IsCollectionHelper(type, out itemType, true /*constructorRequired*/); 1846 } 1847 1848 static Type[] _knownInterfaces; 1849 internal static Type[] KnownInterfaces 1850 { 1851 get 1852 { 1853 if (_knownInterfaces == null) 1854 { 1855 _knownInterfaces = new Type[] 1856 { 1857 Globals.TypeOfIDictionaryGeneric, 1858 Globals.TypeOfIDictionary, 1859 Globals.TypeOfIListGeneric, 1860 Globals.TypeOfICollectionGeneric, 1861 Globals.TypeOfIList, 1862 Globals.TypeOfIEnumerableGeneric, 1863 Globals.TypeOfICollection, 1864 Globals.TypeOfIEnumerable 1865 }; 1866 } 1867 return _knownInterfaces; 1868 } 1869 } 1870 FindCollectionMethodsOnInterface(Type type, Type interfaceType, ref MethodInfo addMethod, ref MethodInfo getEnumeratorMethod)1871 static void FindCollectionMethodsOnInterface(Type type, Type interfaceType, ref MethodInfo addMethod, ref MethodInfo getEnumeratorMethod) 1872 { 1873 InterfaceMapping mapping = type.GetInterfaceMap(interfaceType); 1874 for (int i = 0; i < mapping.TargetMethods.Length; i++) 1875 { 1876 if (mapping.InterfaceMethods[i].Name == Globals.AddMethodName) 1877 addMethod = mapping.InterfaceMethods[i]; 1878 else if (mapping.InterfaceMethods[i].Name == Globals.GetEnumeratorMethodName) 1879 getEnumeratorMethod = mapping.InterfaceMethods[i]; 1880 } 1881 } 1882 IsKnownInterface(Type type)1883 static bool IsKnownInterface(Type type) 1884 { 1885 Type typeToCheck = type.IsGenericType ? type.GetGenericTypeDefinition() : type; 1886 foreach (Type knownInterfaceType in KnownInterfaces) 1887 { 1888 if (typeToCheck == knownInterfaceType) 1889 { 1890 return true; 1891 } 1892 } 1893 return false; 1894 } 1895 GetCollectionMethods(Type type, Type interfaceType, Type[] addMethodTypeArray, bool addMethodOnInterface, out MethodInfo getEnumeratorMethod, out MethodInfo addMethod)1896 static void GetCollectionMethods(Type type, Type interfaceType, Type[] addMethodTypeArray, bool addMethodOnInterface, out MethodInfo getEnumeratorMethod, out MethodInfo addMethod) 1897 { 1898 addMethod = getEnumeratorMethod = null; 1899 1900 if (addMethodOnInterface) 1901 { 1902 addMethod = type.GetMethod(Globals.AddMethodName, BindingFlags.Instance | BindingFlags.Public, null, addMethodTypeArray, null); 1903 if (addMethod == null || addMethod.GetParameters()[0].ParameterType != addMethodTypeArray[0]) 1904 { 1905 FindCollectionMethodsOnInterface(type, interfaceType, ref addMethod, ref getEnumeratorMethod); 1906 if (addMethod == null) 1907 { 1908 Type[] parentInterfaceTypes = interfaceType.GetInterfaces(); 1909 foreach (Type parentInterfaceType in parentInterfaceTypes) 1910 { 1911 if (IsKnownInterface(parentInterfaceType)) 1912 { 1913 FindCollectionMethodsOnInterface(type, parentInterfaceType, ref addMethod, ref getEnumeratorMethod); 1914 if (addMethod == null) 1915 { 1916 break; 1917 } 1918 } 1919 } 1920 } 1921 } 1922 } 1923 else 1924 { 1925 addMethod = type.GetMethod(Globals.AddMethodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, addMethodTypeArray, null); 1926 if (addMethod == null) 1927 return; 1928 } 1929 1930 if (getEnumeratorMethod == null) 1931 { 1932 getEnumeratorMethod = type.GetMethod(Globals.GetEnumeratorMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null); 1933 if (getEnumeratorMethod == null || !Globals.TypeOfIEnumerator.IsAssignableFrom(getEnumeratorMethod.ReturnType)) 1934 { 1935 Type ienumerableInterface = interfaceType.GetInterface("System.Collections.Generic.IEnumerable*"); 1936 if (ienumerableInterface == null) 1937 ienumerableInterface = Globals.TypeOfIEnumerable; 1938 getEnumeratorMethod = GetTargetMethodWithName(Globals.GetEnumeratorMethodName, type, ienumerableInterface); 1939 } 1940 } 1941 } 1942 GetTargetMethodWithName(string name, Type type, Type interfaceType)1943 internal static MethodInfo GetTargetMethodWithName(string name, Type type, Type interfaceType) 1944 { 1945 InterfaceMapping mapping = type.GetInterfaceMap(interfaceType); 1946 for (int i = 0; i < mapping.TargetMethods.Length; i++) 1947 { 1948 if (mapping.InterfaceMethods[i].Name == name) 1949 return mapping.InterfaceMethods[i]; 1950 } 1951 return null; 1952 } Equals(object other)1953 public override bool Equals(object other) 1954 { 1955 if ((object)this == other) 1956 return true; 1957 if (base.Equals(other)) 1958 { 1959 CollectionDataContract collectionContract = other as CollectionDataContract; 1960 if (collectionContract != null) 1961 { 1962 if (!collectionContract.ItemContract.Equals(this.ItemContract)) { return false; } 1963 if (collectionContract.ItemName != this.ItemName) { return false; } 1964 if (collectionContract.KeyName != this.KeyName) { return false; } 1965 if (collectionContract.ValueName != this.ValueName) { return false; } 1966 if (collectionContract.TopLevelElementName != this.TopLevelElementName) { return false; } 1967 if (collectionContract.TopLevelElementNamespace != this.TopLevelElementNamespace) { return false; } 1968 if (collectionContract.IsDictionary != this.IsDictionary) { return false; } 1969 return true; 1970 } 1971 } 1972 return false; 1973 } 1974 GetHashCode()1975 public override int GetHashCode() 1976 { 1977 return base.GetHashCode(); 1978 } 1979 } 1980 1981 public static class Globals 1982 { 1983 internal static Type TypeOfObject = typeof(object); 1984 internal static Type TypeOfValueType = typeof(ValueType); 1985 internal static Type TypeOfArray = typeof(Array); 1986 internal static Type TypeOfEnum = typeof(Enum); 1987 internal static Type TypeOfString = typeof(string); 1988 internal static Type TypeOfStringArray = typeof(string[]); 1989 internal static Type TypeOfInt = typeof(int); 1990 internal static Type TypeOfIntArray = typeof(int[]); 1991 internal static Type TypeOfLong = typeof(long); 1992 internal static Type TypeOfULong = typeof(ulong); 1993 internal static Type TypeOfVoid = typeof(void); 1994 internal static Type TypeOfDouble = typeof(double); 1995 internal static Type TypeOfBool = typeof(bool); 1996 internal static Type TypeOfByte = typeof(byte); 1997 internal static Type TypeOfByteArray = typeof(byte[]); 1998 internal static Type TypeOfTimeSpan = typeof(TimeSpan); 1999 internal static Type TypeOfGuid = typeof(Guid); 2000 internal static Type TypeOfUri = typeof(Uri); 2001 internal static Type TypeOfIntPtr = typeof(IntPtr); 2002 internal static Type TypeOfStreamingContext = typeof(StreamingContext); 2003 internal static Type TypeOfISerializable = typeof(ISerializable); 2004 internal static Type TypeOfIDeserializationCallback = typeof(IDeserializationCallback); 2005 internal static Type TypeOfIObjectReference = typeof(IObjectReference); 2006 internal static Type TypeOfBytePtr = typeof(byte*); 2007 internal static Type TypeOfKnownTypeAttribute = typeof(KnownTypeAttribute); 2008 internal static Type TypeOfDataContractAttribute = typeof(DataContractAttribute); 2009 internal static Type TypeOfContractNamespaceAttribute = typeof(ContractNamespaceAttribute); 2010 internal static Type TypeOfDataMemberAttribute = typeof(DataMemberAttribute); 2011 internal static Type TypeOfOptionalFieldAttribute = typeof(OptionalFieldAttribute); 2012 internal static Type TypeOfObjectArray = typeof(object[]); 2013 internal static Type TypeOfOnSerializingAttribute = typeof(OnSerializingAttribute); 2014 internal static Type TypeOfOnSerializedAttribute = typeof(OnSerializedAttribute); 2015 internal static Type TypeOfOnDeserializingAttribute = typeof(OnDeserializingAttribute); 2016 internal static Type TypeOfOnDeserializedAttribute = typeof(OnDeserializedAttribute); 2017 internal static Type TypeOfFlagsAttribute = typeof(FlagsAttribute); 2018 internal static Type TypeOfSerializableAttribute = typeof(SerializableAttribute); 2019 internal static Type TypeOfSerializationInfo = typeof(SerializationInfo); 2020 internal static Type TypeOfSerializationInfoEnumerator = typeof(SerializationInfoEnumerator); 2021 internal static Type TypeOfSerializationEntry = typeof(SerializationEntry); 2022 internal static Type TypeOfIXmlSerializable = typeof(IXmlSerializable); 2023 internal static Type TypeOfXmlSchemaProviderAttribute = typeof(XmlSchemaProviderAttribute); 2024 internal static Type TypeOfXmlRootAttribute = typeof(XmlRootAttribute); 2025 internal static Type TypeOfXmlQualifiedName = typeof(XmlQualifiedName); 2026 internal static Type TypeOfXmlSchemaType = typeof(XmlSchemaType); 2027 internal static Type TypeOfXmlSchemaSet = typeof(XmlSchemaSet); 2028 internal static object[] EmptyObjectArray = new object[0]; 2029 internal static Type[] EmptyTypeArray = new Type[0]; 2030 internal static Type TypeOfIExtensibleDataObject = typeof(IExtensibleDataObject); 2031 internal static Type TypeOfExtensionDataObject = typeof(ExtensionDataObject); 2032 internal static Type TypeOfNullable = typeof(Nullable<>); 2033 internal static Type TypeOfCollectionDataContractAttribute = typeof(CollectionDataContractAttribute); 2034 internal static Type TypeOfIEnumerable = typeof(IEnumerable); 2035 internal static Type TypeOfIDictionaryGeneric = typeof(IDictionary<,>); 2036 internal static Type TypeOfIEnumerableGeneric = typeof(IEnumerable<>); 2037 internal static Type TypeOfIDictionary = typeof(IDictionary); 2038 internal static Type TypeOfKeyValuePair = typeof(KeyValuePair<,>); 2039 internal static Type TypeOfKeyValue = typeof(KeyValue<,>); 2040 internal static Type TypeOfIListGeneric = typeof(IList<>); 2041 internal static Type TypeOfICollectionGeneric = typeof(ICollection<>); 2042 internal static Type TypeOfIList = typeof(IList); 2043 internal static Type TypeOfICollection = typeof(ICollection); 2044 internal static Type TypeOfIEnumerator = typeof(IEnumerator); 2045 public const string KeyLocalName = "Key"; 2046 public const string ValueLocalName = "Value"; 2047 public const string AddMethodName = "Add"; 2048 public static string SchemaInstanceNamespace = XmlSchema.InstanceNamespace; 2049 public static string SchemaNamespace = XmlSchema.Namespace; 2050 public static string DefaultNamespace = "http://tempuri.org/"; 2051 public static bool DefaultIsRequired = false; 2052 public static int DefaultVersion = 1; 2053 public static string GetEnumeratorMethodName = "GetEnumerator"; 2054 public static string SerializationNamespace = "http://schemas.microsoft.com/2003/10/Serialization/"; 2055 } 2056 } 2057