diff options
author | Jon Skeet <jonskeet@google.com> | 2015-07-01 14:47:03 +0100 |
---|---|---|
committer | Jon Skeet <jonskeet@google.com> | 2015-07-09 08:24:49 +0100 |
commit | 78ea98f56f7a0a028e378aee6394549707e199bc (patch) | |
tree | b3275e8d8b01528dc58af6ec0877c4ee79cd1b54 /csharp/src/ProtocolBuffers/Collections/MapField.cs | |
parent | 3805b43009d35422bed85c56aaf2d6ce4d007fe5 (diff) | |
download | protobuf-78ea98f56f7a0a028e378aee6394549707e199bc.tar.gz protobuf-78ea98f56f7a0a028e378aee6394549707e199bc.tar.bz2 protobuf-78ea98f56f7a0a028e378aee6394549707e199bc.zip |
Implement reflection properly for fields.
- FieldAccessorTable is now non-generic
- We don't have a static field per message type in the umbrella class. (Message descriptors are accessed via the file descriptor.)
- Removed the "descriptor assigner" complication from the descriptor fixup; without extensions, we don't need it
- MapField implements IDictionary (more tests would be good...)
- RepeatedField implements IList (more tests would be good)
- Use expression trees to build accessors. (Will need to test this on various platforms... probably need a fallback strategy just using reflection directly.)
- Added FieldDescriptor.IsMap
- Added tests for reflection with generated messages
Changes to generated code coming in next commit.
Diffstat (limited to 'csharp/src/ProtocolBuffers/Collections/MapField.cs')
-rw-r--r-- | csharp/src/ProtocolBuffers/Collections/MapField.cs | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/csharp/src/ProtocolBuffers/Collections/MapField.cs b/csharp/src/ProtocolBuffers/Collections/MapField.cs index 6d1097a6..779ff061 100644 --- a/csharp/src/ProtocolBuffers/Collections/MapField.cs +++ b/csharp/src/ProtocolBuffers/Collections/MapField.cs @@ -48,7 +48,7 @@ namespace Google.Protobuf.Collections /// </remarks> /// <typeparam name="TKey">Key type in the map. Must be a type supported by Protocol Buffer map keys.</typeparam> /// <typeparam name="TValue">Value type in the map. Must be a type supported by Protocol Buffers.</typeparam> - public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IFreezable, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>> + public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IFreezable, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary { // TODO: Don't create the map/list until we have an entry. (Assume many maps will be empty.) private bool frozen; @@ -64,7 +64,7 @@ namespace Google.Protobuf.Collections { foreach (var pair in list) { - clone.Add(pair.Key, pair.Value == null ? pair.Value : ((IDeepCloneable<TValue>) pair.Value).Clone()); + clone.Add(pair.Key, pair.Value == null ? pair.Value : ((IDeepCloneable<TValue>)pair.Value).Clone()); } } else @@ -309,7 +309,7 @@ namespace Google.Protobuf.Collections /// </remarks> /// <param name="input">Stream to read from</param> /// <param name="codec">Codec describing how the key/value pairs are encoded</param> - public void AddEntriesFrom(CodedInputStream input, Codec codec) + public void AddEntriesFrom(CodedInputStream input, Codec codec) { var adapter = new Codec.MessageAdapter(codec); do @@ -318,7 +318,7 @@ namespace Google.Protobuf.Collections input.ReadMessage(adapter); this[adapter.Key] = adapter.Value; } while (input.MaybeConsumeTag(codec.MapTag)); - } + } public void WriteTo(CodedOutputStream output, Codec codec) { @@ -350,6 +350,67 @@ namespace Google.Protobuf.Collections return size; } + #region IDictionary explicit interface implementation + void IDictionary.Add(object key, object value) + { + Add((TKey)key, (TValue)value); + } + + bool IDictionary.Contains(object key) + { + if (!(key is TKey)) + { + return false; + } + return ContainsKey((TKey)key); + } + + IDictionaryEnumerator IDictionary.GetEnumerator() + { + throw new NotImplementedException(); + } + + void IDictionary.Remove(object key) + { + if (!(key is TKey)) + { + return; + } + Remove((TKey)key); + } + + void ICollection.CopyTo(Array array, int index) + { + throw new NotImplementedException(); + } + + bool IDictionary.IsFixedSize { get { return IsFrozen; } } + + ICollection IDictionary.Keys { get { return (ICollection)Keys; } } + + ICollection IDictionary.Values { get { return (ICollection)Values; } } + + bool ICollection.IsSynchronized { get { return false; } } + + object ICollection.SyncRoot { get { return null; } } + + object IDictionary.this[object key] + { + get + { + if (!(key is TKey)) + { + return null; + } + TValue value; + TryGetValue((TKey)key, out value); + return value; + } + + set { this[(TKey)key] = (TValue)value; } + } + #endregion + /// <summary> /// A codec for a specific map field. This contains all the information required to encoded and /// decode the nested messages. |