Skip to content
This repository has been archived by the owner on Aug 2, 2023. It is now read-only.

Added System.Memory.Polyfill Project #2339

Merged
merged 14 commits into from
Jun 5, 2018

Conversation

KrzysztofCwalina
Copy link
Member

This project is a skeleton for an adapter package that allows writing portable code using Span<T>-enabled APIs that are found in .NET Core 2.1 but not in other versions/redists of .NET.

For example, .NET Core 2.1 Stream has a Read method that takes a Span<byte> parameter. This member does not exist in other .NET versions, which makes is difficult to write portable code (such portable code has to "manually" cross-target).

This library hide cross-targeting inside adapter APIs.

{
public static partial class Int32Polyfill
{
public static bool TryParse(ReadOnlySpan<char> buffer, out int value)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would,'t work for implicit cast from Span<char>?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not? It's not an extension method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, true... Is a bit ugly then :)

Static extension method would be better dotnet/csharplang#192 though alas not a thing...

<Description>Adapters for Span APIs</Description>
<TargetFrameworks>netstandard1.3;netcoreapp2.1</TargetFrameworks>
<PackageTags>Span Memory Adapter</PackageTags>
<!-- disable automatic compile item inclusion so that we can set the correct metadata on TextTemplate-generated sources -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't actually have any of these, so you can remove this and the compile entry below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do.

public static bool TryParse(ReadOnlySpan<char> buffer, out int value)
{
#if NETCOREAPP2_1
return int.TryParse(buffer, out value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may want to avoid using the versioned define as it makes it more difficult if you decide to retarget. Instead use #if NETCOREAPP

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this api exists only in netcoreapp 2.1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You aren't defining targeting here, you're just ifdefing the code. Imagine that you wanted to cross-compile for netcoreapp2.2 as well in the future, you'd need to touch this ifdef for no reason. I think you're more likely to cross-compile for a future version of netcoreapp than you are an older version that doesn't have this API.
Alternatively you can define your own feature flag that represents what you want and make sure that's defined as appropriate.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree it would work today, but it won't if we ever add new targets. Correct?

<Import Project="..\..\tools\common.props" />
<PropertyGroup>
<TargetFrameworks>net46;netcoreapp2.1</TargetFrameworks>
<AssemblyOriginatorKeyFile>../../tools/test_key.snk</AssemblyOriginatorKeyFile>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the properties from here on look unnecessary for a test project.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I just copied them from some other test, but I will remove/simplify. Thanks.

</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Memory" Version="$(SystemMemoryVersion)" />
<PackageReference Include="System.Buffers" Version="$(SystemMemoryVersion)" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use SystemBuffersVersion instead of SystemMemoryVersion.


namespace System
{
public static partial class MemoryPolyfill
Copy link
Member

@ahsonkhan ahsonkhan Jun 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StreamPolyfill instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to minimize the number of extensions types.

public void Int32TryParse()
{
char[] buffer = int.MaxValue.ToString().ToCharArray();
ReadOnlySpan<char> span = buffer.AsSpan();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReadOnlySpan<char> span = int.MaxValue.ToString().AsSpan();?

@KrzysztofCwalina
Copy link
Member Author

@dotnet-bot test Innerloop Ubuntu16.04 Release Build and Test

@KrzysztofCwalina KrzysztofCwalina merged commit 697d518 into dotnet:master Jun 5, 2018
<TargetFrameworks>net46;netcoreapp2.1</TargetFrameworks>
<AssemblyOriginatorKeyFile>../../tools/test_key.snk</AssemblyOriginatorKeyFile>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove these properties?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericstj suggested that they were not necessary for tests.

@@ -1,13 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\tools\common.props" />
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetsWindows)' == 'true'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is listing netcoreapp2.1 TFM here redundant or required (for Windows only)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it in the new PR. This actually did not work in the CI. I changed it to use netcoreapp2.0 to force the fallback path.

@@ -11,8 +11,7 @@ public class Int32Tests
[Fact]
public void Int32TryParse()
{
char[] buffer = int.MaxValue.ToString().ToCharArray();
ReadOnlySpan<char> span = buffer.AsSpan();
ReadOnlySpan<char> span = int.MaxValue.ToString().ToCharArray().AsSpan();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the .ToCharArray() necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in the new PR

@KrzysztofCwalina KrzysztofCwalina deleted the Polyfill branch October 26, 2018 21:34
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants