public static bool Equal(object x, object y) { if (ReferenceEquals(x, y)) { return(true); } if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) { return(ReferenceEquals(x, y)); } var type = x.GetType(); if (y.GetType() != type) { throw new ArgumentException("Types of x and y do not match."); } if (TypeUtils.IsAListCollectionType(type)) { return(ListsEqual((IList)x, (IList)y)); } if (TypeUtils.IsASetCollectionType(type)) { return(SetsEqual((IEnumerable)x, (IEnumerable)y)); } if (TypeUtils.IsADictionaryCollectionType(type)) { return(DictionariesEqual((IDictionary)x, (IDictionary)y)); } return(x.Equals(y)); }
/// <summary> /// Encode a collection /// </summary> ByteString EncodeCollection(Type type, object value) { if (TypeUtils.IsAListCollectionType(type)) { var encodedList = new Schema.KRPC.List(); var list = (System.Collections.IList)value; var valueType = type.GetGenericArguments().Single(); foreach (var item in list) { encodedList.Items.Add(Encode(valueType, item)); } return(ProtocolBuffers.WriteMessage(encodedList)); } else if (TypeUtils.IsADictionaryCollectionType(type)) { var keyType = type.GetGenericArguments() [0]; var valueType = type.GetGenericArguments() [1]; var encodedDictionary = new Schema.KRPC.Dictionary(); foreach (System.Collections.DictionaryEntry entry in (System.Collections.IDictionary)value) { var encodedEntry = new Schema.KRPC.DictionaryEntry(); encodedEntry.Key = Encode(keyType, entry.Key); encodedEntry.Value = Encode(valueType, entry.Value); encodedDictionary.Entries.Add(encodedEntry); } return(ProtocolBuffers.WriteMessage(encodedDictionary)); } else if (TypeUtils.IsASetCollectionType(type)) { var encodedSet = new Schema.KRPC.Set(); var set = (System.Collections.IEnumerable)value; var valueType = type.GetGenericArguments().Single(); foreach (var item in set) { encodedSet.Items.Add(Encode(valueType, item)); } return(ProtocolBuffers.WriteMessage(encodedSet)); } else // a tuple // TODO: this is ugly { var encodedTuple = new Schema.KRPC.Tuple(); var valueTypes = type.GetGenericArguments().ToArray(); var genericType = Type.GetType("KRPC.Utils.Tuple`" + valueTypes.Length); var tupleType = genericType.MakeGenericType(valueTypes); for (int i = 0; i < valueTypes.Length; i++) { var property = tupleType.GetProperty("Item" + (i + 1)); var item = property.GetGetMethod().Invoke(value, null); encodedTuple.Items.Add(Encode(valueTypes [i], item)); } return(ProtocolBuffers.WriteMessage(encodedTuple)); } }
/// <summary> /// Decode a serialized collection /// </summary> object DecodeCollection(ProcedureSignature procedure, int i, Type type, ByteString value) { if (TypeUtils.IsAListCollectionType(type)) { var encodedList = Schema.KRPC.List.Parser.ParseFrom(value); var list = (System.Collections.IList)(typeof(System.Collections.Generic.List <>) .MakeGenericType(type.GetGenericArguments().Single()) .GetConstructor(Type.EmptyTypes) .Invoke(null)); foreach (var item in encodedList.Items) { list.Add(Decode(procedure, i, type.GetGenericArguments().Single(), item)); } return(list); } else if (TypeUtils.IsADictionaryCollectionType(type)) { var encodedDictionary = Schema.KRPC.Dictionary.Parser.ParseFrom(value); var dictionary = (System.Collections.IDictionary)(typeof(System.Collections.Generic.Dictionary <,>) .MakeGenericType(type.GetGenericArguments() [0], type.GetGenericArguments() [1]) .GetConstructor(Type.EmptyTypes) .Invoke(null)); foreach (var entry in encodedDictionary.Entries) { var k = Decode(procedure, i, type.GetGenericArguments() [0], entry.Key); var v = Decode(procedure, i, type.GetGenericArguments() [1], entry.Value); dictionary [k] = v; } return(dictionary); } else if (TypeUtils.IsASetCollectionType(type)) { var encodedSet = Schema.KRPC.Set.Parser.ParseFrom(value); var set = (System.Collections.IEnumerable)(typeof(System.Collections.Generic.HashSet <>) .MakeGenericType(type.GetGenericArguments().Single()) .GetConstructor(Type.EmptyTypes) .Invoke(null)); MethodInfo methodInfo = type.GetMethod("Add"); foreach (var item in encodedSet.Items) { var decodedItem = Decode(procedure, i, type.GetGenericArguments().Single(), item); methodInfo.Invoke(set, new [] { decodedItem }); } return(set); } else // a tuple // TODO: this is ugly { var encodedTuple = Schema.KRPC.Tuple.Parser.ParseFrom(value); var valueTypes = type.GetGenericArguments().ToArray(); var genericType = Type.GetType("KRPC.Utils.Tuple`" + valueTypes.Length); Object[] values = new Object[valueTypes.Length]; for (int j = 0; j < valueTypes.Length; j++) { var item = encodedTuple.Items [j]; values [j] = Decode(procedure, i, valueTypes [j], item); } var tuple = genericType .MakeGenericType(valueTypes) .GetConstructor(valueTypes) .Invoke(values); return(tuple); } }