3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
11 ** Purpose: Writes primitive values to a stream
14 ===========================================================*/
16 namespace System.Runtime.Serialization.Formatters.Binary {
19 using System.Collections;
21 using System.Reflection;
23 using System.Globalization;
24 using System.Runtime.Serialization.Formatters;
25 using System.Configuration.Assemblies;
26 using System.Threading;
27 using System.Runtime.Remoting;
28 using System.Runtime.Serialization;
30 internal sealed class __BinaryWriter
33 internal FormatterTypeStyle formatterTypeStyle;
34 internal Hashtable objectMapTable;
35 internal ObjectWriter objectWriter = null;
36 internal BinaryWriter dataWriter = null;
38 // disable csharp compiler warning #0414: field assigned unused value
39 #pragma warning disable 0414
40 internal int m_nestedObjectCount;
41 #pragma warning restore 0414
42 private int nullCount = 0; //Count of consecutive array nulls
45 internal __BinaryWriter(Stream sout, ObjectWriter objectWriter, FormatterTypeStyle formatterTypeStyle)
47 SerTrace.Log( this, "BinaryWriter ");
49 this.formatterTypeStyle = formatterTypeStyle;
50 this.objectWriter = objectWriter;
51 m_nestedObjectCount = 0;
52 dataWriter = new BinaryWriter(sout, Encoding.UTF8);
55 internal void WriteBegin()
57 BCLDebug.Trace("BINARY", "\n%%%%%BinaryWriterBegin%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
60 internal void WriteEnd()
62 BCLDebug.Trace("BINARY", "\n%%%%%BinaryWriterEnd%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
66 // Methods to write a value onto the stream
67 internal void WriteBoolean(Boolean value)
69 dataWriter.Write(value);
72 internal void WriteByte(Byte value)
74 dataWriter.Write(value);
77 private void WriteBytes(Byte[] value)
79 dataWriter.Write(value);
82 private void WriteBytes(byte[] byteA, int offset, int size)
84 dataWriter.Write(byteA, offset, size);
87 internal void WriteChar(Char value)
89 dataWriter.Write(value);
92 internal void WriteChars(Char[] value)
94 dataWriter.Write(value);
98 internal void WriteDecimal(Decimal value)
100 WriteString(value.ToString(CultureInfo.InvariantCulture));
103 internal void WriteSingle(Single value)
105 dataWriter.Write(value);
108 internal void WriteDouble(Double value)
110 dataWriter.Write(value);
113 internal void WriteInt16(Int16 value)
115 dataWriter.Write(value);
118 internal void WriteInt32(Int32 value)
120 dataWriter.Write(value);
123 internal void WriteInt64(Int64 value)
125 dataWriter.Write(value);
128 internal void WriteSByte(SByte value)
130 WriteByte((Byte)value);
133 internal void WriteString(String value)
135 dataWriter.Write(value);
138 internal void WriteTimeSpan(TimeSpan value)
140 WriteInt64(value.Ticks);
143 internal void WriteDateTime(DateTime value)
145 WriteInt64(value.ToBinaryRaw());
148 internal void WriteUInt16(UInt16 value)
150 dataWriter.Write(value);
153 internal void WriteUInt32(UInt32 value)
155 dataWriter.Write(value);
158 internal void WriteUInt64(UInt64 value)
160 dataWriter.Write(value);
163 internal void WriteObjectEnd(NameInfo memberNameInfo, NameInfo typeNameInfo)
167 internal void WriteSerializationHeaderEnd()
169 MessageEnd record = new MessageEnd();
174 // Methods to write Binary Serialization Record onto the stream, a record is composed of primitive types
176 internal void WriteSerializationHeader(int topId, int headerId, int minorVersion, int majorVersion)
178 SerializationHeaderRecord record = new SerializationHeaderRecord(BinaryHeaderEnum.SerializedStreamHeader, topId, headerId, minorVersion, majorVersion);
184 internal BinaryMethodCall binaryMethodCall;
185 internal void WriteMethodCall()
187 if (binaryMethodCall == null)
188 binaryMethodCall = new BinaryMethodCall();
190 binaryMethodCall.Dump();
191 binaryMethodCall.Write(this);
194 internal Object[] WriteCallArray(String uri, String methodName, String typeName, Type[] instArgs, Object[] args, Object methodSignature, Object callContext, Object[] properties)
196 if (binaryMethodCall == null)
197 binaryMethodCall = new BinaryMethodCall();
198 return binaryMethodCall.WriteArray(uri, methodName, typeName, instArgs, args, methodSignature, callContext, properties);
201 internal BinaryMethodReturn binaryMethodReturn;
202 internal void WriteMethodReturn()
204 if (binaryMethodReturn == null)
205 binaryMethodReturn = new BinaryMethodReturn();
206 binaryMethodReturn.Dump();
207 binaryMethodReturn.Write(this);
210 internal Object[] WriteReturnArray(Object returnValue, Object[] args, Exception exception, Object callContext, Object[] properties)
212 if (binaryMethodReturn == null)
213 binaryMethodReturn = new BinaryMethodReturn();
214 return binaryMethodReturn.WriteArray(returnValue, args, exception, callContext, properties);
217 internal BinaryObject binaryObject;
218 internal BinaryObjectWithMap binaryObjectWithMap;
219 internal BinaryObjectWithMapTyped binaryObjectWithMapTyped;
220 //internal BinaryCrossAppDomainMap crossAppDomainMap;
222 internal void WriteObject(NameInfo nameInfo, NameInfo typeNameInfo, int numMembers, String[] memberNames, Type[] memberTypes, WriteObjectInfo[] memberObjectInfos)
224 InternalWriteItemNull();
227 nameInfo.Dump("WriteObject nameInfo");
228 typeNameInfo.Dump("WriteObject typeNameInfo");
231 int objectId = (int)nameInfo.NIobjectId;
234 // objectId = --m_nestedObjectCount;
238 BCLDebug.Trace("BINARY", "-----Top Level Object-----");
241 String objectName = null;
245 objectName = typeNameInfo.NIname;
250 objectName = nameInfo.NIname;
252 SerTrace.Log( this, "WriteObject objectName ",objectName);
254 if (objectMapTable == null)
256 objectMapTable = new Hashtable();
259 ObjectMapInfo objectMapInfo = (ObjectMapInfo)objectMapTable[objectName];
261 if (objectMapInfo != null && objectMapInfo.isCompatible(numMembers, memberNames, memberTypes))
264 if (binaryObject == null)
265 binaryObject = new BinaryObject();
266 binaryObject.Set(objectId, objectMapInfo.objectId);
270 binaryObject.Write(this);
272 else if (!typeNameInfo.NItransmitTypeOnObject)
276 if (binaryObjectWithMap == null)
277 binaryObjectWithMap = new BinaryObjectWithMap();
279 // BCL types are not placed into table
280 assemId = (int)typeNameInfo.NIassemId;
281 binaryObjectWithMap.Set(objectId, objectName, numMembers, memberNames, assemId);
283 binaryObjectWithMap.Dump();
284 binaryObjectWithMap.Write(this);
285 if (objectMapInfo == null)
286 objectMapTable.Add(objectName, new ObjectMapInfo(objectId, numMembers, memberNames, memberTypes));
290 // ObjectWithMapTyped
291 BinaryTypeEnum[] binaryTypeEnumA = new BinaryTypeEnum[numMembers];
292 Object[] typeInformationA = new Object[numMembers];
293 int[] assemIdA = new int[numMembers];
294 for (int i=0; i<numMembers; i++)
296 Object typeInformation = null;
298 binaryTypeEnumA[i] = BinaryConverter.GetBinaryTypeInfo(memberTypes[i], memberObjectInfos[i], null, objectWriter, out typeInformation, out assemId);
299 typeInformationA[i] = typeInformation;
300 assemIdA[i] = assemId;
301 SerTrace.Log( this, "WriteObject ObjectWithMapTyped memberNames "
302 ,memberNames[i],", memberType ",memberTypes[i]," binaryTypeEnum ",((Enum)binaryTypeEnumA[i]).ToString()
303 ,", typeInformation ",typeInformationA[i]," assemId ",assemIdA[i]);
306 if (binaryObjectWithMapTyped == null)
307 binaryObjectWithMapTyped = new BinaryObjectWithMapTyped();
309 // BCL types are not placed in table
310 assemId = (int)typeNameInfo.NIassemId;
311 binaryObjectWithMapTyped.Set(objectId, objectName, numMembers,memberNames, binaryTypeEnumA, typeInformationA, assemIdA, assemId);
313 binaryObjectWithMapTyped.Dump();
315 binaryObjectWithMapTyped.Write(this);
316 if (objectMapInfo == null)
317 objectMapTable.Add(objectName, new ObjectMapInfo(objectId, numMembers, memberNames, memberTypes));
321 internal BinaryObjectString binaryObjectString;
322 internal BinaryCrossAppDomainString binaryCrossAppDomainString;
324 internal void WriteObjectString(int objectId, String value)
326 InternalWriteItemNull();
328 if (binaryObjectString == null)
329 binaryObjectString = new BinaryObjectString();
330 binaryObjectString.Set(objectId, value);
332 binaryObjectString.Dump();
334 binaryObjectString.Write(this);
337 internal BinaryArray binaryArray;
339 [System.Security.SecurityCritical] // auto-generated
340 internal void WriteSingleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, Array array)
342 InternalWriteItemNull();
344 arrayNameInfo.Dump("WriteSingleArray arrayNameInfo");
345 arrayElemTypeNameInfo.Dump("WriteSingleArray arrayElemTypeNameInfo");
347 BinaryArrayTypeEnum binaryArrayTypeEnum;
348 Int32[] lengthA = new Int32[1];
350 Int32[] lowerBoundA = null;
351 Object typeInformation = null;
355 binaryArrayTypeEnum = BinaryArrayTypeEnum.Single;
359 binaryArrayTypeEnum = BinaryArrayTypeEnum.SingleOffset;
360 lowerBoundA = new Int32[1];
361 lowerBoundA[0] = lowerBound;
366 BinaryTypeEnum binaryTypeEnum = BinaryConverter.GetBinaryTypeInfo(arrayElemTypeNameInfo.NItype, objectInfo, arrayElemTypeNameInfo.NIname, objectWriter, out typeInformation, out assemId);
368 if (binaryArray == null)
369 binaryArray = new BinaryArray();
370 binaryArray.Set((int)arrayNameInfo.NIobjectId, (int)1, lengthA, lowerBoundA, binaryTypeEnum, typeInformation, binaryArrayTypeEnum, assemId);
372 if (arrayNameInfo.NIobjectId >0)
374 BCLDebug.Trace("BINARY", "-----Top Level Object-----");
379 binaryArray.Write(this);
381 if (Converter.IsWriteAsByteArray(arrayElemTypeNameInfo.NIprimitiveTypeEnum) && (lowerBound == 0))
383 //array is written out as an array of bytes
384 if (arrayElemTypeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.Byte)
385 WriteBytes((Byte[])array);
386 else if (arrayElemTypeNameInfo.NIprimitiveTypeEnum == InternalPrimitiveTypeE.Char)
387 WriteChars((char[])array);
389 WriteArrayAsBytes(array, Converter.TypeLength(arrayElemTypeNameInfo.NIprimitiveTypeEnum));
393 byte[] byteBuffer = null;
394 int chunkSize = 4096;
396 [System.Security.SecurityCritical] // auto-generated
397 private void WriteArrayAsBytes(Array array, int typeLength)
399 InternalWriteItemNull();
400 int byteLength = array.Length*typeLength;
402 if (byteBuffer == null)
403 byteBuffer = new byte[chunkSize];
405 while (arrayOffset < array.Length)
407 int numArrayItems = Math.Min(chunkSize/typeLength, array.Length-arrayOffset);
408 int bufferUsed = numArrayItems*typeLength;
409 Buffer.InternalBlockCopy(array, arrayOffset*typeLength, byteBuffer, 0, bufferUsed);
410 if (!BitConverter.IsLittleEndian) {
411 // we know that we are writing a primitive type, so just do a simple swap
412 for (int i = 0; i < bufferUsed; i += typeLength)
414 for (int j = 0; j < typeLength / 2; j++)
416 byte tmp = byteBuffer[i + j];
417 byteBuffer[i + j] = byteBuffer[i + typeLength-1 - j];
418 byteBuffer[i + typeLength-1 - j] = tmp;
422 WriteBytes(byteBuffer, 0, bufferUsed);
423 arrayOffset += numArrayItems;
428 internal void WriteJaggedArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound)
431 arrayNameInfo.Dump("WriteRectangleArray arrayNameInfo");
432 arrayElemTypeNameInfo.Dump("WriteRectangleArray arrayElemTypeNameInfo");
434 InternalWriteItemNull();
435 BinaryArrayTypeEnum binaryArrayTypeEnum;
436 Int32[] lengthA = new Int32[1];
438 Int32[] lowerBoundA = null;
439 Object typeInformation = null;
444 binaryArrayTypeEnum = BinaryArrayTypeEnum.Jagged;
448 binaryArrayTypeEnum = BinaryArrayTypeEnum.JaggedOffset;
449 lowerBoundA = new Int32[1];
450 lowerBoundA[0] = lowerBound;
453 BinaryTypeEnum binaryTypeEnum = BinaryConverter.GetBinaryTypeInfo(arrayElemTypeNameInfo.NItype, objectInfo, arrayElemTypeNameInfo.NIname, objectWriter, out typeInformation, out assemId);
455 if (binaryArray == null)
456 binaryArray = new BinaryArray();
457 binaryArray.Set((int)arrayNameInfo.NIobjectId, (int)1, lengthA, lowerBoundA, binaryTypeEnum, typeInformation, binaryArrayTypeEnum, assemId);
459 if (arrayNameInfo.NIobjectId >0)
461 BCLDebug.Trace("BINARY", "-----Top Level Object-----");
466 binaryArray.Write(this);
469 internal void WriteRectangleArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int rank, int[] lengthA, int[] lowerBoundA)
472 arrayNameInfo.Dump("WriteRectangleArray arrayNameInfo");
473 arrayElemTypeNameInfo.Dump("WriteRectangleArray arrayElemTypeNameInfo");
475 InternalWriteItemNull();
477 BinaryArrayTypeEnum binaryArrayTypeEnum = BinaryArrayTypeEnum.Rectangular;
478 Object typeInformation = null;
480 BinaryTypeEnum binaryTypeEnum = BinaryConverter.GetBinaryTypeInfo(arrayElemTypeNameInfo.NItype, objectInfo, arrayElemTypeNameInfo.NIname, objectWriter, out typeInformation, out assemId);
482 if (binaryArray == null)
483 binaryArray = new BinaryArray();
485 for (int i=0; i<rank; i++)
487 if (lowerBoundA[i] != 0)
489 binaryArrayTypeEnum = BinaryArrayTypeEnum.RectangularOffset;
495 binaryArray.Set((int)arrayNameInfo.NIobjectId, rank, lengthA, lowerBoundA, binaryTypeEnum, typeInformation, binaryArrayTypeEnum, assemId);
497 if (arrayNameInfo.NIobjectId >0)
499 BCLDebug.Trace("BINARY", "-----Top Level Object-----");
504 binaryArray.Write(this);
508 [System.Security.SecurityCritical] // auto-generated
509 internal void WriteObjectByteArray(NameInfo memberNameInfo, NameInfo arrayNameInfo, WriteObjectInfo objectInfo, NameInfo arrayElemTypeNameInfo, int length, int lowerBound, Byte[] byteA)
512 arrayNameInfo.Dump("WriteObjectByteArray arrayNameInfo");
513 arrayElemTypeNameInfo.Dump("WriteObjectByteArray arrayElemTypeNameInfo");
515 InternalWriteItemNull();
516 WriteSingleArray(memberNameInfo, arrayNameInfo, objectInfo, arrayElemTypeNameInfo, length, lowerBound, byteA);
519 internal MemberPrimitiveUnTyped memberPrimitiveUnTyped;
520 internal MemberPrimitiveTyped memberPrimitiveTyped;
522 internal void WriteMember(NameInfo memberNameInfo, NameInfo typeNameInfo, Object value)
525 SerTrace.Log("BinaryWriter", "Write Member memberName ",memberNameInfo.NIname,", value ",value);
526 memberNameInfo.Dump("WriteMember memberNameInfo");
527 typeNameInfo.Dump("WriteMember typeNameInfo");
529 InternalWriteItemNull();
530 InternalPrimitiveTypeE typeInformation = typeNameInfo.NIprimitiveTypeEnum;
532 // Writes Members with primitive values
534 if (memberNameInfo.NItransmitTypeOnMember)
536 if (memberPrimitiveTyped == null)
537 memberPrimitiveTyped = new MemberPrimitiveTyped();
538 memberPrimitiveTyped.Set((InternalPrimitiveTypeE)typeInformation, value);
540 if (memberNameInfo.NIisArrayItem)
542 BCLDebug.Trace("BINARY", "-----item-----");
546 BCLDebug.Trace("BINARY","-----",memberNameInfo.NIname,"-----");
548 memberPrimitiveTyped.Dump();
550 memberPrimitiveTyped.Write(this);
554 if (memberPrimitiveUnTyped == null)
555 memberPrimitiveUnTyped = new MemberPrimitiveUnTyped();
556 memberPrimitiveUnTyped.Set(typeInformation, value);
558 if (memberNameInfo.NIisArrayItem)
560 BCLDebug.Trace("BINARY", "-----item-----");
564 BCLDebug.Trace("BINARY", "-----",memberNameInfo.NIname,"-----");
566 memberPrimitiveUnTyped.Dump();
568 memberPrimitiveUnTyped.Write(this);
573 internal ObjectNull objectNull;
576 internal void WriteNullMember(NameInfo memberNameInfo, NameInfo typeNameInfo)
579 typeNameInfo.Dump("WriteNullMember typeNameInfo");
581 InternalWriteItemNull();
582 if (objectNull == null)
583 objectNull = new ObjectNull();
585 if (memberNameInfo.NIisArrayItem)
587 BCLDebug.Trace("BINARY", "-----item-----");
591 objectNull.SetNullCount(1);
592 BCLDebug.Trace("BINARY", "-----",memberNameInfo.NIname,"-----");
594 objectNull.Write(this);
599 internal MemberReference memberReference;
601 internal void WriteMemberObjectRef(NameInfo memberNameInfo, int idRef)
603 InternalWriteItemNull();
604 if (memberReference == null)
605 memberReference = new MemberReference();
606 memberReference.Set(idRef);
608 if (memberNameInfo.NIisArrayItem)
610 BCLDebug.Trace("BINARY", "-----item-----");
614 BCLDebug.Trace("BINARY", "-----",memberNameInfo.NIname,"-----");
616 memberReference.Dump();
618 memberReference.Write(this);
621 internal void WriteMemberNested(NameInfo memberNameInfo)
623 InternalWriteItemNull();
624 if (memberNameInfo.NIisArrayItem)
626 BCLDebug.Trace("BINARY", "-----item-----");
630 BCLDebug.Trace("BINARY", "-----",memberNameInfo.NIname,"-----");
634 internal void WriteMemberString(NameInfo memberNameInfo, NameInfo typeNameInfo, String value)
636 InternalWriteItemNull();
637 if (memberNameInfo.NIisArrayItem)
639 BCLDebug.Trace("BINARY", "-----item-----");
643 BCLDebug.Trace("BINARY", "-----",memberNameInfo.NIname,"-----");
645 WriteObjectString((int)typeNameInfo.NIobjectId, value);
648 internal void WriteItem(NameInfo itemNameInfo, NameInfo typeNameInfo, Object value)
650 InternalWriteItemNull();
651 WriteMember(itemNameInfo, typeNameInfo, value);
654 internal void WriteNullItem(NameInfo itemNameInfo, NameInfo typeNameInfo)
657 InternalWriteItemNull();
660 internal void WriteDelayedNullItem()
665 internal void WriteItemEnd()
667 InternalWriteItemNull();
670 private void InternalWriteItemNull()
674 if (objectNull == null)
675 objectNull = new ObjectNull();
676 objectNull.SetNullCount(nullCount);
677 BCLDebug.Trace("BINARY", "-----item-----");
679 objectNull.Write(this);
684 internal void WriteItemObjectRef(NameInfo nameInfo, int idRef)
686 InternalWriteItemNull();
687 WriteMemberObjectRef(nameInfo, idRef);
691 internal BinaryAssembly binaryAssembly;
692 internal BinaryCrossAppDomainAssembly crossAppDomainAssembly;
694 internal void WriteAssembly(Type type, String assemblyString, int assemId, bool isNew)
696 SerTrace.Log( this,"WriteAssembly type ",type,", id ",assemId,", name ", assemblyString,", isNew ",isNew);
697 //If the file being tested wasn't built as an assembly, then we're going to get null back
698 //for the assembly name. This is very unfortunate.
699 InternalWriteItemNull();
700 if (assemblyString==null)
702 assemblyString=String.Empty;
707 if (binaryAssembly == null)
708 binaryAssembly = new BinaryAssembly();
709 binaryAssembly.Set(assemId, assemblyString);
710 binaryAssembly.Dump();
711 binaryAssembly.Write(this);
715 // Method to write a value onto a stream given its primitive type code
716 internal void WriteValue(InternalPrimitiveTypeE code, Object value)
718 SerTrace.Log( this, "WriteValue Entry ",((Enum)code).ToString()," " , ((value==null)?"<null>":value.GetType().ToString()) , " ",value);
722 case InternalPrimitiveTypeE.Boolean:
723 WriteBoolean(Convert.ToBoolean(value, CultureInfo.InvariantCulture));
725 case InternalPrimitiveTypeE.Byte:
726 WriteByte(Convert.ToByte(value, CultureInfo.InvariantCulture));
728 case InternalPrimitiveTypeE.Char:
729 WriteChar(Convert.ToChar(value, CultureInfo.InvariantCulture));
731 case InternalPrimitiveTypeE.Double:
732 WriteDouble(Convert.ToDouble(value, CultureInfo.InvariantCulture));
734 case InternalPrimitiveTypeE.Int16:
735 WriteInt16(Convert.ToInt16(value, CultureInfo.InvariantCulture));
737 case InternalPrimitiveTypeE.Int32:
738 WriteInt32(Convert.ToInt32(value, CultureInfo.InvariantCulture));
740 case InternalPrimitiveTypeE.Int64:
741 WriteInt64(Convert.ToInt64(value, CultureInfo.InvariantCulture));
743 case InternalPrimitiveTypeE.SByte:
744 WriteSByte(Convert.ToSByte(value, CultureInfo.InvariantCulture));
746 case InternalPrimitiveTypeE.Single:
747 WriteSingle(Convert.ToSingle(value, CultureInfo.InvariantCulture));
749 case InternalPrimitiveTypeE.UInt16:
750 WriteUInt16(Convert.ToUInt16(value, CultureInfo.InvariantCulture));
752 case InternalPrimitiveTypeE.UInt32:
753 WriteUInt32(Convert.ToUInt32(value, CultureInfo.InvariantCulture));
755 case InternalPrimitiveTypeE.UInt64:
756 WriteUInt64(Convert.ToUInt64(value, CultureInfo.InvariantCulture));
758 case InternalPrimitiveTypeE.Decimal:
759 WriteDecimal(Convert.ToDecimal(value, CultureInfo.InvariantCulture));
761 case InternalPrimitiveTypeE.TimeSpan:
762 WriteTimeSpan((TimeSpan)value);
764 case InternalPrimitiveTypeE.DateTime:
765 WriteDateTime((DateTime)value);
768 throw new SerializationException(Environment.GetResourceString("Serialization_TypeCode",((Enum)code).ToString()));
770 SerTrace.Log( this, "Write Exit ");
774 internal sealed class ObjectMapInfo
776 internal int objectId;
778 String[] memberNames;
781 internal ObjectMapInfo(int objectId, int numMembers, String[] memberNames, Type[] memberTypes)
783 this.objectId = objectId;
784 this.numMembers = numMembers;
785 this.memberNames = memberNames;
786 this.memberTypes = memberTypes;
789 internal bool isCompatible(int numMembers, String[] memberNames, Type[] memberTypes)
792 if (this.numMembers == numMembers)
794 for (int i=0; i<numMembers; i++)
796 if (!(this.memberNames[i].Equals(memberNames[i])))
801 if ((memberTypes != null) && (this.memberTypes[i] != memberTypes[i]))