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

This closes #2328
diff --git a/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj b/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj
index 35138d8..baef759 100644
--- a/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj
+++ b/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj
@@ -20,12 +20,12 @@
   
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <TargetFrameworks>netcoreapp3.1;net48</TargetFrameworks>
+    <TargetFrameworks>net5.0;net48</TargetFrameworks>
     <TieredCompilation>false</TieredCompilation>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
+    <PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
index 1726ddb..807f767 100644
--- a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
+++ b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
@@ -19,7 +19,7 @@
   -->
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
     <AssemblyName>Thrift.IntegrationTests</AssemblyName>
     <PackageId>Thrift.IntegrationTests</PackageId>
     <Version>0.15.0.0</Version>
@@ -33,11 +33,11 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="CompareNETObjects" Version="4.64.0" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
-    <PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
-    <PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.7.0" />
+    <PackageReference Include="CompareNETObjects" Version="4.72.0" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
+    <PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
+    <PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="4.8.1" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
index af28cd9..759c42f 100644
--- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
@@ -19,7 +19,7 @@
   -->
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
     <Version>0.15.0.0</Version>
     <AssemblyName>Thrift.PublicInterfaces.Compile.Tests</AssemblyName>
     <PackageId>Thrift.PublicInterfaces.Compile.Tests</PackageId>
@@ -34,7 +34,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.7.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="4.8.1" />
   </ItemGroup>
 
   <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
diff --git a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
index a03e646..4e21a26 100644
--- a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
+++ b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
@@ -18,15 +18,15 @@
     under the License.
   -->
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
     <Version>0.15.0.0</Version>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="CompareNETObjects" Version="4.64.0" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
-    <PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
-    <PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
-    <PackageReference Include="NSubstitute" Version="4.2.1" />
+    <PackageReference Include="CompareNETObjects" Version="4.72.0" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
+    <PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
+    <PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
+    <PackageReference Include="NSubstitute" Version="4.2.2" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
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);