THRIFT-5216 generate DeepCopy methods
Client: netstd
Patch: Jens Geyer

This closes #2155
diff --git a/lib/netstd/Thrift/Collections/TCollections.cs b/lib/netstd/Thrift/Collections/TCollections.cs
index 147bfc7..b386c37 100644
--- a/lib/netstd/Thrift/Collections/TCollections.cs
+++ b/lib/netstd/Thrift/Collections/TCollections.cs
@@ -16,11 +16,12 @@
 // under the License.
 
 using System.Collections;
+using System.Collections.Generic;
 
 namespace Thrift.Collections
 {
     // ReSharper disable once InconsistentNaming
-    public class TCollections
+    public static class TCollections
     {
         /// <summary>
         ///     This will return true if the two collections are value-wise the same.
@@ -38,6 +39,18 @@
                 return false;
             }
 
+            // for dictionaries, we need to compare keys and values separately
+            // because KeyValuePair<K,V>.Equals() will not do what we want
+            var fdict = first as IDictionary;
+            var sdict = second as IDictionary;
+            if ((fdict != null) || (sdict != null))
+            {
+                if ((fdict == null) || (sdict == null))
+                    return false;
+                return TCollections.Equals(fdict.Keys, sdict.Keys)
+                    && TCollections.Equals(fdict.Values, sdict.Values);
+            }
+
             var fiter = first.GetEnumerator();
             var siter = second.GetEnumerator();
 
@@ -91,11 +104,13 @@
 
                 unchecked
                 {
-                    hashcode = (hashcode*397) ^ (objHash);
+                    hashcode = (hashcode * 397) ^ (objHash);
                 }
             }
 
             return hashcode;
         }
+
+
     }
-}
\ No newline at end of file
+}
diff --git a/lib/netstd/Thrift/Collections/THashSet.cs b/lib/netstd/Thrift/Collections/THashSet.cs
index ffab577..8dfb9e3 100644
--- a/lib/netstd/Thrift/Collections/THashSet.cs
+++ b/lib/netstd/Thrift/Collections/THashSet.cs
@@ -60,12 +60,12 @@
             Items.CopyTo(array, arrayIndex);
         }
 
-        public IEnumerator GetEnumerator()
+        IEnumerator IEnumerable.GetEnumerator()
         {
             return Items.GetEnumerator();
         }
 
-        IEnumerator<T> IEnumerable<T>.GetEnumerator()
+        public IEnumerator<T> GetEnumerator()
         {
             return ((IEnumerable<T>) Items).GetEnumerator();
         }
diff --git a/lib/netstd/Thrift/Protocol/TBase.cs b/lib/netstd/Thrift/Protocol/TBase.cs
index b5ef2ae..df9dd34 100644
--- a/lib/netstd/Thrift/Protocol/TBase.cs
+++ b/lib/netstd/Thrift/Protocol/TBase.cs
@@ -22,12 +22,13 @@
 {
     public interface TUnionBase
     {
-        Task WriteAsync(TProtocol tProtocol, CancellationToken cancellationToken = default(CancellationToken));
+        Task WriteAsync(TProtocol tProtocol, CancellationToken cancellationToken = default);
     }
 
     // ReSharper disable once InconsistentNaming
     public interface TBase : TUnionBase
     {
-        Task ReadAsync(TProtocol tProtocol, CancellationToken cancellationToken = default(CancellationToken));
+        Task ReadAsync(TProtocol tProtocol, CancellationToken cancellationToken = default);
     }
+
 }
diff --git a/lib/netstd/Thrift/Collections/ToStringExtension.cs b/lib/netstd/Thrift/Protocol/ToString.cs
similarity index 95%
rename from lib/netstd/Thrift/Collections/ToStringExtension.cs
rename to lib/netstd/Thrift/Protocol/ToString.cs
index 40dd9dd..14fa520 100644
--- a/lib/netstd/Thrift/Collections/ToStringExtension.cs
+++ b/lib/netstd/Thrift/Protocol/ToString.cs
@@ -21,7 +21,7 @@
 using System.Text;
 using Thrift.Protocol;
 
-namespace Thrift.Collections
+namespace Thrift.Protocol
 {
 
 
@@ -73,7 +73,7 @@
             }
             else
             {
-                sb.Append(self.ToString());
+                sb.Append(self != null?  self.ToString() : "<null>");
             }
         }
     }