aboutsummaryrefslogtreecommitdiff
path: root/csharp/src/ProtocolBuffers/Collections/MapField.cs
diff options
context:
space:
mode:
authorJon Skeet <jonskeet@google.com>2015-07-01 14:47:03 +0100
committerJon Skeet <jonskeet@google.com>2015-07-09 08:24:49 +0100
commit78ea98f56f7a0a028e378aee6394549707e199bc (patch)
treeb3275e8d8b01528dc58af6ec0877c4ee79cd1b54 /csharp/src/ProtocolBuffers/Collections/MapField.cs
parent3805b43009d35422bed85c56aaf2d6ce4d007fe5 (diff)
downloadprotobuf-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.cs69
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.