SubType.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #if !NO_RUNTIME
  2. using System;
  3. using ProtoBuf.Serializers;
  4. namespace ProtoBuf.Meta
  5. {
  6. /// <summary>
  7. /// Represents an inherited type in a type hierarchy.
  8. /// </summary>
  9. public sealed class SubType
  10. {
  11. internal sealed class Comparer : System.Collections.IComparer
  12. #if !NO_GENERICS
  13. , System.Collections.Generic.IComparer<SubType>
  14. #endif
  15. {
  16. public static readonly Comparer Default = new Comparer();
  17. public int Compare(object x, object y)
  18. {
  19. return Compare(x as SubType, y as SubType);
  20. }
  21. public int Compare(SubType x, SubType y)
  22. {
  23. if (ReferenceEquals(x, y)) return 0;
  24. if (x == null) return -1;
  25. if (y == null) return 1;
  26. return x.FieldNumber.CompareTo(y.FieldNumber);
  27. }
  28. }
  29. private readonly int fieldNumber;
  30. /// <summary>
  31. /// The field-number that is used to encapsulate the data (as a nested
  32. /// message) for the derived dype.
  33. /// </summary>
  34. public int FieldNumber { get { return fieldNumber; } }
  35. /// <summary>
  36. /// The sub-type to be considered.
  37. /// </summary>
  38. public MetaType DerivedType { get { return derivedType; } }
  39. private readonly MetaType derivedType;
  40. /// <summary>
  41. /// Creates a new SubType instance.
  42. /// </summary>
  43. /// <param name="fieldNumber">The field-number that is used to encapsulate the data (as a nested
  44. /// message) for the derived dype.</param>
  45. /// <param name="derivedType">The sub-type to be considered.</param>
  46. /// <param name="format">Specific encoding style to use; in particular, Grouped can be used to avoid buffering, but is not the default.</param>
  47. public SubType(int fieldNumber, MetaType derivedType, DataFormat format)
  48. {
  49. if (derivedType == null) throw new ArgumentNullException("derivedType");
  50. if (fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber");
  51. this.fieldNumber = fieldNumber;
  52. this.derivedType = derivedType;
  53. this.dataFormat = format;
  54. }
  55. private readonly DataFormat dataFormat;
  56. private IProtoSerializer serializer;
  57. internal IProtoSerializer Serializer
  58. {
  59. get
  60. {
  61. if (serializer == null) serializer = BuildSerializer();
  62. return serializer;
  63. }
  64. }
  65. private IProtoSerializer BuildSerializer()
  66. {
  67. // note the caller here is MetaType.BuildSerializer, which already has the sync-lock
  68. WireType wireType = WireType.String;
  69. if(dataFormat == DataFormat.Group) wireType = WireType.StartGroup; // only one exception
  70. IProtoSerializer ser = new SubItemSerializer(derivedType.Type, derivedType.GetKey(false, false), derivedType, false);
  71. return new TagDecorator(fieldNumber, wireType, false, ser);
  72. }
  73. }
  74. }
  75. #endif