THRIFT-5349 Add net5.0 as supported platform
Client: netstd
Patch: Jens Geyer

This closes #2328
diff --git a/lib/netstd/Thrift/Collections/TCollections.cs b/lib/netstd/Thrift/Collections/TCollections.cs
index b386c37..21ee3bb 100644
--- a/lib/netstd/Thrift/Collections/TCollections.cs
+++ b/lib/netstd/Thrift/Collections/TCollections.cs
@@ -99,8 +99,7 @@
 
             foreach (var obj in enumerable)
             {
-                var enum2 = obj as IEnumerable;
-                var objHash = enum2 == null ? obj.GetHashCode() : GetHashCode(enum2);
+                var objHash = (obj is IEnumerable enum2) ? GetHashCode(enum2) : obj.GetHashCode();
 
                 unchecked
                 {
diff --git a/lib/netstd/Thrift/Collections/THashSet.cs b/lib/netstd/Thrift/Collections/THashSet.cs
index 8dfb9e3..25fcf10 100644
--- a/lib/netstd/Thrift/Collections/THashSet.cs
+++ b/lib/netstd/Thrift/Collections/THashSet.cs
@@ -32,8 +32,13 @@
 
         public THashSet(int capacity)
         {
-            // TODO: uncomment capacity when NET Standard also implements it
-            Items = new HashSet<T>(/*capacity*/);
+            #if NET5_0
+            Items = new HashSet<T>(capacity);
+            #elif NETFRAMEWORK || NETSTANDARD
+            Items = new HashSet<T>(/*capacity not supported*/);
+            #else
+            #error Unknown platform
+            #endif
         }
 
         public int Count => Items.Count;
diff --git a/lib/netstd/Thrift/Protocol/TBase.cs b/lib/netstd/Thrift/Protocol/TBase.cs
index df9dd34..09bb43f 100644
--- a/lib/netstd/Thrift/Protocol/TBase.cs
+++ b/lib/netstd/Thrift/Protocol/TBase.cs
@@ -18,6 +18,8 @@
 using System.Threading;
 using System.Threading.Tasks;
 
+#pragma warning disable IDE1006   // some interfaces here are intentionally not I-prefixed 
+
 namespace Thrift.Protocol
 {
     public interface TUnionBase
diff --git a/lib/netstd/Thrift/Thrift.csproj b/lib/netstd/Thrift/Thrift.csproj
index 46db1aa..4372334 100644
--- a/lib/netstd/Thrift/Thrift.csproj
+++ b/lib/netstd/Thrift/Thrift.csproj
@@ -19,7 +19,7 @@
   -->
 
 <PropertyGroup>
-  <TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks>
+  <TargetFrameworks>netstandard2.1;netstandard2.0;net5.0</TargetFrameworks>
   <AssemblyName>Thrift</AssemblyName>
   <PackageId>ApacheThrift</PackageId>
   <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
@@ -55,16 +55,16 @@
 
   <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
-    <PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.0" />
-    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.0" />
-    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.0" />
+    <PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="5.0.0" />
     <PackageReference Include="System.IO.Pipes" Version="[4.3,)" />
-    <PackageReference Include="System.IO.Pipes.AccessControl" Version="4.5.1" />
-    <PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.7.0" />
+    <PackageReference Include="System.IO.Pipes.AccessControl" Version="5.0.0" />
+    <PackageReference Include="System.Net.Http.WinHttpHandler" Version="5.0.0" />
     <PackageReference Include="System.Net.NameResolution" Version="[4.3,)" />
     <PackageReference Include="System.Net.Requests" Version="[4.3,)" />
     <PackageReference Include="System.Net.Security" Version="4.3.2" />
-    <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
+    <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
   </ItemGroup>
 
   <Target Name="SetTFMAssemblyAttributesPath" BeforeTargets="GenerateTargetFrameworkMonikerAttribute">
diff --git a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
index 3381110..5698776 100644
--- a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
+++ b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
@@ -139,7 +139,7 @@
 
         private const string Kernel32 = "kernel32.dll";
 
-        [DllImport(Kernel32, SetLastError = true)]
+        [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
         internal static extern IntPtr CreateNamedPipe(
             string lpName, uint dwOpenMode, uint dwPipeMode,
             uint nMaxInstances, uint nOutBufferSize, uint nInBufferSize, uint nDefaultTimeOut,
@@ -156,9 +156,9 @@
         // - https://github.com/dotnet/corefx/issues/31190 System.IO.Pipes.AccessControl package does not work
         // - https://github.com/dotnet/corefx/issues/24040 NamedPipeServerStream: Provide support for WRITE_DAC
         // - https://github.com/dotnet/corefx/issues/34400 Have a mechanism for lower privileged user to connect to a privileged user's pipe
-        private SafePipeHandle CreatePipeNative(string name, int inbuf, int outbuf)
+        private static SafePipeHandle CreatePipeNative(string name, int inbuf, int outbuf)
         {
-            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+            if (! RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                 return null; // Windows only
 
             var pinningHandle = new GCHandle();
@@ -279,7 +279,9 @@
                 }
 
                 CheckReadBytesAvailable(length);
-#if NETSTANDARD2_1
+#if NET5_0
+                var numBytes = await PipeStream.ReadAsync(buffer.AsMemory(offset, length), cancellationToken);
+#elif NETSTANDARD2_1
                 var numBytes = await PipeStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
 #else
                 var numBytes = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken);
@@ -301,7 +303,11 @@
                 var nBytes = Math.Min(15 * 4096, length); // 16 would exceed the limit
                 while (nBytes > 0)
                 {
+#if NET5_0
+                    await PipeStream.WriteAsync(buffer.AsMemory(offset, nBytes), cancellationToken);
+#else
                     await PipeStream.WriteAsync(buffer, offset, nBytes, cancellationToken);
+#endif
                     offset += nBytes;
                     length -= nBytes;
                     nBytes = Math.Min(nBytes, length);