Add .NET debugging attributes (#14097)

I've been working with a large Protobuf model and noticed debugging issues that can easily be improved.

Add debugging attributes to collections, `ByteString`, and descriptors. No impact on runtime behavior. Debugger type proxies are what the debugger displays by default, but full data is available by selecting "Raw View".

`RepeatedField` and `MapField` now display their item count. This is standard across .NET collections. For example, .NET's list and dictionary both display `Count = {Count}`.

Note that previously, Protobuf collections displayed the result of `ToString`, which returned JSON. The JSON debug view isn't useful when there is too much content to display at once because it's truncated. That experience will be fairly common.

Count benefits:
* Always useful
* Makes debugging Protobuf collections feel more like regular .NET collections
* Collection contents is now easier to access with debugger type proxies

No dependency between this PR and https://github.com/protocolbuffers/protobuf/pull/13838. Each can be merged independently.

**MapField before:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/9dd3baa9-4432-446e-9049-1f7268d5be4c)

**MapField after:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/ac4aea33-e339-49e0-9a67-c174d2608393)

**RepeatedField before:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/16353785-bef4-4489-a3ab-de2437d51d4e)

**RepeatedField after:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/f3de7680-ded9-41d8-aac0-84a9e7b65c98)

**ByteString before:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/4febc400-1eb7-46ee-911e-a7698783a358)

**ByteString after:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/7635080e-9bb0-4f61-9a39-afbb9e575051)

**Descriptor before:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/5b89792b-a16a-4641-a50c-5355b5230b5d)

**Descriptor after:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/5047dc1e-c93b-43d5-bb8c-a6976a9ae6da)

**TypeRegistry before:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/d4aedf19-22cc-49b5-8717-9299e00abc85)

**TypeRegistry after:**

![image](https://github.com/protocolbuffers/protobuf/assets/303201/4a473595-74b9-40e2-96b8-2b103d5f44b0)

Closes #14097

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/14097 from JamesNK:jamesnk/debugging f0dea3464d471042a59e9c0000a5e65e8c9bc46b
PiperOrigin-RevId: 568444117
diff --git a/csharp/src/Google.Protobuf/Collections/MapField.cs b/csharp/src/Google.Protobuf/Collections/MapField.cs
index 2e18976..f0be958 100644
--- a/csharp/src/Google.Protobuf/Collections/MapField.cs
+++ b/csharp/src/Google.Protobuf/Collections/MapField.cs
@@ -11,6 +11,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using System.Security;
@@ -43,6 +44,8 @@
     /// in future versions.
     /// </para>
     /// </remarks>
+    [DebuggerDisplay("Count = {Count}")]
+    [DebuggerTypeProxy(typeof(MapField<,>.MapFieldDebugView))]
     public sealed class MapField<TKey, TValue> : IDeepCloneable<MapField<TKey, TValue>>, IDictionary<TKey, TValue>, IEquatable<MapField<TKey, TValue>>, IDictionary, IReadOnlyDictionary<TKey, TValue>
     {
         private static readonly EqualityComparer<TValue> ValueEqualityComparer = ProtobufEqualityComparers.GetEqualityComparer<TValue>();
@@ -683,5 +686,18 @@
                 }
             }
         }
+
+        private sealed class MapFieldDebugView
+        {
+            private readonly MapField<TKey, TValue> map;
+
+            public MapFieldDebugView(MapField<TKey, TValue> map)
+            {
+                this.map = map;
+            }
+
+            [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
+            public KeyValuePair<TKey, TValue>[] Items => map.list.ToArray();
+        }
     }
 }