VinlandSolutions.CommonCore.Shims 1.0.0-pre.3

This is a prerelease version of VinlandSolutions.CommonCore.Shims.
dotnet add package VinlandSolutions.CommonCore.Shims --version 1.0.0-pre.3
NuGet\Install-Package VinlandSolutions.CommonCore.Shims -Version 1.0.0-pre.3
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="VinlandSolutions.CommonCore.Shims" Version="1.0.0-pre.3" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add VinlandSolutions.CommonCore.Shims --version 1.0.0-pre.3
#r "nuget: VinlandSolutions.CommonCore.Shims, 1.0.0-pre.3"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install VinlandSolutions.CommonCore.Shims as a Cake Addin
#addin nuget:?package=VinlandSolutions.CommonCore.Shims&version=1.0.0-pre.3&prerelease

// Install VinlandSolutions.CommonCore.Shims as a Cake Tool
#tool nuget:?package=VinlandSolutions.CommonCore.Shims&version=1.0.0-pre.3&prerelease

Vinland Solutions CommonCore.Shims Library

License Platform Repository Releases Documentation
Nuget Pipeline Coverage

NOTE: This project should only be used by legacy pre-dotnet core projects and libraries that multi-target net standard 2.0 to reach such projects.

CommonCore.Shims is a .Net Standard 2.0/2.1 library that provides shims for C# 9 features like collection slicing and initializable properties.

Installation

The official release versions of the CommonCore.Shims library are hosted on NuGet and can be installed using the standard console means, or found through the Visual Studio NuGet Package Managers.

This library is compatible with projects targeting at least .Net Framework 4.6.1, .Net Core 2.0, or .Net 5.

Usage

This library does not have any special usage of it's own. It simply enables C# language features that are usually present but unusable in projects targeting net standard 2.1 or lower. It may be necessary to explicitly enable C# 9 language features, in which case a LangVersion element must be added to the project file.

    <PropertyGroup>
        <TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks>
        <LangVersion>9.0</LangVersion>
    </PropertyGroup>

Otherwise, most shimmed features work without any additional effort.

Externally initializable properties:

public class SomeClass
{
    public int InitProp { get; init; } = 10;
}

var sc = new SomeClass();
Console.WriteLine(sc.InitProp);// InitProp == 10
sc = new SomeClass() { InitProp = 5 };
Console.WriteLine(sc.InitProp);// InitProp == 5
sc.InitProp = 0;// Error

Some code analysis attributes:

public static bool TryParse(
    [NotNullWhen(true)] object? input,
    [NotNullWhen(true), MaybeNullWhen(false)] out SomeType? output)
{
    // if input is not null and can parse input,
    // then set output to result and return true,
    // else set output null and return false.
}

However, there is one more additional step required to convince the compiler that collection slicing is enabled. C# language features, like slicing, seem fancy, but they boil down to calling methods just like any other code. In this case, slicing calls the GetSubArray() method on the RuntimeHelpers class in the System.Runtime.CompilerServices.

Without that method, slicing won't work. Unfortunately, unlike most shimming solutions, the library can't simply declare the class and implement the method to solve this one. The reason is that the class already exists, but the net standard 2.0 version of the class doesn't have the neeeded method. If the library declared the class with the method and made public so other libraries could have it for their compiler, it would still be an error because the compiler sees two versions of the same class. However, there is a loophole.

The problem isn't the compiler seeing two versions of the same class. The problem is the compiler seeing to public versions of the same class. If the class is internal, then the problem goes away. The compiler can find the needed method on the class and isn't confused because of public ambiguity. But if the class is in the library and internal, then that doesn't help anyone other than me writing this library. The solution is straight forward at this point.

Consuming projects must define the class themselves and it has to be internal. The library does wrap the implementation of the GetSubArray(), so it can wrapped to avoid too much bloat. It is highly suggested to put the class in a file named __RuntimeHelpers.cs, note the two leading underscores, or nest it in a System/Runtime/CompilerServices/RuntimeHelpers.cs folder hierarchy, or in some other way make it very apparent that the code isn't a normal part of the library.

THe code is wrapped in an if-directive so it is only included in the compilation for the needed frameworks. A short comment is given to the class so anyone viewing the file can have an idea why it exists. The inheritdoc tag is used to attach more detailed information to the method itself from it's wrapped counter part. Lastly, the ExcludeFromCodeCoverage and EditorBrowsable attributes are used to hide the class from code coverage stats and intellisence code completion, respectively.

#if !NETSTANDARD2_1_OR_GREATER

using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;

namespace System.Runtime.CompilerServices
{
    /// <summary>
    /// Shim class to enable C# 9 slicing feature.
    /// Uses CommonCore.Shims for implementation.
    /// </summary>
    [ExcludeFromCodeCoverage]
    [EditorBrowsable(EditorBrowsableState.Never)]
    internal static class RuntimeHelpers
    {
        /// <inheritdoc cref="CommonCore.Shims.RuntimeHelpers.GetSubArray{T}(T[], Range)"/>
        public static T[] GetSubArray<T>(T[] array, Range range)
            => CommonCore.Shims.RuntimeHelpers.GetSubArray(array, range);
    }
}

#endif

Once that method is available to the compiler, collection slicing should work as one would expect.

Slicing collections:

int[] array = new int[] { 9, 5, 1 };
int[] subarray;
subarray = array[1..];// { 5, 1 }
subarray = array[..^1];// { 9, 5 }
subarray = array[1..^1];// { 5 }

Projects

The CommonCore.Shims repository is composed of three projects with the listed dependencies:

Credits

This library simply wraps some dotnet types that are built-in for net standard 2.1 and greater, so thanks goes to the dotnet team.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on VinlandSolutions.CommonCore.Shims:

Package Downloads
VinlandSolutions.CommonCore.Exceptions

CommonCore.Exceptions is a .Net Standard 2.0/2.1 library designed to simplify the validating and throwing of common exceptions.

VinlandSolutions.CommonCore.Text

CommonCore.Text is a .Net Standard 2.0/2.1 library ?.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0-pre.3 148 4/10/2022
1.0.0-pre.2 152 4/8/2022
1.0.0-pre.1 104 4/7/2022

# Release v1.0.0-pre.2

* Library now targets both net standard 2.0 and 2.1 [#1](https://gitlab.com/commoncorelibs/commoncore-shims/-/issues/1)
* Fix init properties unavailable in dotnet standard 2.1 [#1](https://gitlab.com/commoncorelibs/commoncore-shims/-/issues/1)