FrameworkExtensions.Backports
1.0.0.183
See the version list below for details.
dotnet add package FrameworkExtensions.Backports --version 1.0.0.183
NuGet\Install-Package FrameworkExtensions.Backports -Version 1.0.0.183
<PackageReference Include="FrameworkExtensions.Backports" Version="1.0.0.183" />
<PackageVersion Include="FrameworkExtensions.Backports" Version="1.0.0.183" />
<PackageReference Include="FrameworkExtensions.Backports" />
paket add FrameworkExtensions.Backports --version 1.0.0.183
#r "nuget: FrameworkExtensions.Backports, 1.0.0.183"
#:package FrameworkExtensions.Backports@1.0.0.183
#addin nuget:?package=FrameworkExtensions.Backports&version=1.0.0.183
#tool nuget:?package=FrameworkExtensions.Backports&version=1.0.0.183
FrameworkExtensions.Backports
Overview
FrameworkExtensions.Backports is a NuGet package that provides a collection of extensions (Polyfills) to ensure that newer compiler features work in older versions of the .NET Framework/Standard/Core. This package allows developers to use modern C# language features and .NET APIs even when working on projects targeting earlier versions down to Net2.0.
Note: Performance is not a primary concern here. This focuses mainly on functionality and ready-to-be-built without making adjustments to code.
Architecture
Official Package Integration
To avoid conflicts with official Microsoft BCL backport packages and ensure optimal compatibility, FrameworkExtensions.Backports uses a hybrid approach:
When official packages exist: For target frameworks where Microsoft provides official backport packages (such as System.Memory, System.Buffers, System.ValueTuple, etc.), this package automatically references and uses those official implementations.
When official packages don't exist: For older target frameworks (like .NET Framework 2.0, 3.5) or for features not covered by official packages, this package provides custom backport implementations.
This approach means:
- ✅ Users only need to reference
FrameworkExtensions.Backports- all necessary dependencies are included automatically - ✅ No package conflicts - official implementations are used when available, avoiding type conflicts
- ✅ Better performance and compatibility - official Microsoft implementations are optimized and thoroughly tested
- ✅ Seamless experience - the same API surface works across all target frameworks
Official Packages Included
The following official Microsoft packages are conditionally referenced based on your target framework:
Active Packages:
- System.Memory - Provides
Span<T>,ReadOnlySpan<T>,Memory<T>, andMemoryMarshal(.NET Framework 4.5+, .NET Standard 2.0) - System.Buffers - Provides
ArrayPool<T>(.NET Framework 4.5+, .NET Standard 2.0) - System.ValueTuple - Provides
ValueTupletypes (.NET Framework 4.0+) - System.Runtime.CompilerServices.Unsafe - Provides the
Unsafeclass (.NET Framework 4.5+, .NET Standard 1.0+) - System.Numerics.Vectors - Provides
Vectortypes (.NET Framework 4.5+, .NET Standard 2.0) - System.Threading.Tasks.Extensions - Provides
ValueTask(.NET Framework 4.5+, .NET Standard 2.0) - Microsoft.Bcl.HashCode - Provides
HashCode(.NET Framework 4.6.1+, .NET Standard 2.0)
Deprecated Packages (still included for compatibility):
- Microsoft.Bcl - Provides
CallerMemberNameAttributeand related attributes (.NET Framework 4.0 only) - Microsoft.Bcl.Async - Provides
TaskAwaiterand async/await support (.NET Framework 4.0 only)
Note: Microsoft.Bcl and Microsoft.Bcl.Async are officially deprecated but are still included for .NET Framework 4.0 to avoid conflicts with existing projects that may reference these packages.
For target frameworks where these packages are not available (e.g., .NET Framework 2.0/3.5), custom implementations are provided.
Features
Interfaces
System
- IGrouping<out TKey, TElement>
- IParsable
- ISpanFormattable
- ISpanParsable
System.Collections
System
System.Collections.Generic
- IAsyncEnumerable<T>
- IAsyncEnumerator<T>
- IReadOnlyDictionary<TKey, TValue>
System.Runtime.CompilerServices
Types
System
System
System.Buffers
- ArrayPool<T>
- IMemoryOwner<T>
- MemoryManager<T>
- MemoryPool<T>
- ReadOnlySequence<T>
- ReadOnlySequenceSegment<T>
- SequenceReader<T>
System.Collections.Concurrent
- ConcurrentBag<T>
- ConcurrentDictionary<TKey, TValue>
- ConcurrentQueue<T>
- ConcurrentStack<T>
System.Collections.Generic
- HashSet<T>
- ReadOnlyDictionary<TKey, TValue>
System.Numerics
System.Runtime.CompilerServices
System.Runtime.InteropServices
System.Runtime.Intrinsics
System.Runtime.Intrinsics.Arm
System.Runtime.Intrinsics.X86
System.Threading
Attributes
System.Diagnostics
System.Diagnostics.CodeAnalysis
System.Runtime.CompilerServices
- AsyncIteratorStateMachine
- CallerArgumentExpression
- CallerFilePath
- CallerLineNumber
- CallerMemberName
- CollectionBuilder
- CompilerFeatureRequired
- EnumeratorCancellation
- Extension
- InlineArray
- InterpolatedStringHandler
- InterpolatedStringHandlerArgument
- ModuleInitializer
- OverloadResolutionPriority
- RefSafetyRules
- RequiredMember
- TupleElementNames
Delegates
Static Methods
System.Array
System.IO.Path
- string Join(string path1, string path2)
- string Join(string path1, string path2, string path3)
- string Join(string path1, string path2, string path3, string path4)
- string Join(params string[] paths)
- string GetRelativePath(string relativeTo, string path)
System.Math
- T Clamp(T value, T min, T max) - for byte, sbyte, short, ushort, int, uint, long, ulong, float, double, decimal
System.DateTime
- DateTime UnixEpoch
- DateTime Parse
- DateTime ParseExact
- bool TryParse
- bool TryParseExact
- DateTime FromDateAndTime
System.Single (float)
- bool IsFinite
- bool IsNegative
- bool IsNormal
- bool IsSubnormal
- float Lerp
- float DegreesToRadians
- float RadiansToDegrees
System.Random
- Random Shared (static property)
System.String
- string Create<TState>(int length, TState state, SpanAction<char, TState> action)
System.ArgumentNullException
- void ThrowIfNull(object? argument, string? paramName = null)
- void ThrowIfNull(void* argument, string? paramName = null)
System.ArgumentException
- void ThrowIfNullOrEmpty(string? argument, string? paramName = null)
- void ThrowIfNullOrWhiteSpace(string? argument, string? paramName = null)
System.ArgumentOutOfRangeException
- void ThrowIfZero<T>(T value, string? paramName = null)
- void ThrowIfNegative<T>(T value, string? paramName = null)
- void ThrowIfNegativeOrZero<T>(T value, string? paramName = null)
- void ThrowIfGreaterThan<T>(T value, T other, string? paramName = null)
- void ThrowIfGreaterThanOrEqual<T>(T value, T other, string? paramName = null)
- void ThrowIfLessThan<T>(T value, T other, string? paramName = null)
- void ThrowIfLessThanOrEqual<T>(T value, T other, string? paramName = null)
- void ThrowIfEqual<T>(T value, T other, string? paramName = null)
- void ThrowIfNotEqual<T>(T value, T other, string? paramName = null)
System.ObjectDisposedException
Methods
System.Array
System.ReadOnlySpan
- bool SequenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other)
- bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other)
- bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other, IEqualityComparer<T> comparer)
- int IndexOf<T>(this ReadOnlySpan<T> span, T value)
- int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value)
- int IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
- int LastIndexOf<T>(this ReadOnlySpan<T> span, T value)
- int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value)
- int LastIndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
- bool StartsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
- bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value)
- bool StartsWith<T>(this Span<T> span, ReadOnlySpan<T> value)
System.Collections.Concurrent.ConcurrentBag
- void Clear<T>(this ConcurrentBag<T>)
System.Collections.Concurrent.ConcurrentDictionary
- TValue AddOrUpdate<TKey, TValue, TArg>(this ConcurrentDictionary<TKey, TValue> @this, TKey key, Func<TKey, TArg, TValue> addValueFactory, Func<TKey, TValue, TArg, TValue> updateValueFactory, TArg factoryArgument)
System.Collections.Concurrent.ConcurrentQueue
- void Clear<T>(this ConcurrentQueue<T>)
System.Collections.Concurrent.ConcurrentStack
- void Clear<T>(this ConcurrentStack<T>)
System.Collections.Generic.IEnumerable
System.Collections.Generic.KeyValuePair
- void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> @this, out TKey key, out TValue value)
System.Collections.Generic.Stack
System.DateTime
- int Microsecond(this DateTime @this)
- int Nanosecond(this DateTime @this)
- DateTime AddMicroseconds(this DateTime @this, double value)
- bool TryFormat(this DateTime @this, Span<char> destination, out int charsWritten, ...)
- void Deconstruct(this DateTime @this, out DateOnly date, out TimeOnly time)
- void Deconstruct(this DateTime @this, out int year, out int month, out int day)
System.DateTimeOffset
- long ToUnixTimeMilliseconds(this DateTimeOffset @this)
- long ToUnixTimeSeconds(this DateTimeOffset @this)
System.Diagnostics
- void Restart(this Stopwatch @this)
System.Enum
- bool HasFlag<T>(this T @this, T flag)
System.IO.DirectoryInfo
- IEnumerable<FileSystemInfo> EnumerateFileSystemInfos(this DirectoryInfo @this)
- IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo @this)
- IEnumerable<DirectoryInfo> EnumerateDirectories(this DirectoryInfo @this)
- IEnumerable<FileInfo> EnumerateFiles(this DirectoryInfo @this, string searchPattern, SearchOption searchOption)
- IEnumerable<DirectoryInfo> EnumerateDirectories(this DirectoryInfo @this, string searchPattern, SearchOption searchOption)
System.IO.FileInfo
- void MoveTo(this FileInfo @this, string destFileName, bool overwrite)
System.IO.Stream
- void CopyTo(this Stream @this, Stream target)
- void Flush(this Stream @this, bool flushToDisk)
- Task<int> ReadAsync(this Stream @this, byte[] buffer, int offset, int count)
- Task<int> ReadAsync(this Stream @this, byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- Task WriteAsync(this Stream @this, byte[] buffer, int offset, int count)
- Task WriteAsync(this Stream @this, byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- Task CopyToAsync(this Stream @this, Stream destination, int bufferSize, CancellationToken cancellationToken)
- int Read(this Stream @this, Span<byte> buffer)
- void Write(this Stream @this, ReadOnlySpan<byte> buffer)
System.Linq
- TResult[] ToArray<TResult>(this IEnumerable<TResult> @this)
- IEnumerable<TResult> Cast<TResult>(this IEnumerable @this)
- IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate)
- IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> @this, Func<TSource, int, bool> predicate)
- IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> @this, Func<TSource, TResult> selector)
- IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> @this, Func<TSource, int, TResult> selector)
- IEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> @this, Func<TSource, TKey> keySelector)
- IEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> @this, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
- IEnumerable<TSource> ThenBy<TSource, TKey>(this IEnumerable<TSource> @this, Func<TSource, TKey> keySelector)
- IEnumerable<TSource> ThenBy<TSource, TKey>(this IEnumerable<TSource> @this, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
- TSource First<TSource>(this IEnumerable<TSource> @this)
- TSource First<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate)
- TSource FirstOrDefault<TSource>(this IEnumerable<TSource> @this)
- TSource FirstOrDefault<TSource>(this IEnumerable<TSource> @this, TSource defaultValue)
- TSource FirstOrDefault<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate)
- TSource FirstOrDefault<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate, TSource defaultValue)
- TSource Single<TSource>(this IEnumerable<TSource> @this)
- TSource Single<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate)
- TSource SingleOrDefault<TSource>(this IEnumerable<TSource> @this)
- TSource SingleOrDefault<TSource>(this IEnumerable<TSource> @this, TSource defaultValue)
- TSource SingleOrDefault<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate, TSource defaultValue)
- TSource SingleOrDefault<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate)
- TSource Last<TSource>(this IEnumerable<TSource> @this)
- TSource Last<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate)
- TSource LastOrDefault<TSource>(this IEnumerable<TSource> @this)
- TSource LastOrDefault<TSource>(this IEnumerable<TSource> @this, TSource defaultValue)
- TSource LastOrDefault<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate)
- TSource LastOrDefault<TSource>(this IEnumerable<TSource> @this, Func<TSource, bool> predicate, TSource defaultValue)
- TSource Min<TSource>(this IEnumerable<TSource> source)
- TItem MinBy<TItem, TKey>(this IEnumerable<TItem> @this, Func<TItem, TKey> keySelector)
- TItem MinBy<TItem, TKey>(this IEnumerable<TItem> @this, Func<TItem, TKey> keySelector, IComparer<TKey> comparer)
- TSource Max<TSource>(this IEnumerable<TSource> source)
- TItem MaxBy<TItem, TKey>(this IEnumerable<TItem> @this, Func<TItem, TKey> keySelector)
- TItem MaxBy<TItem, TKey>(this IEnumerable<TItem> @this, Func<TItem, TKey> keySelector, IComparer<TKey> comparer)
- IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
- IEnumerable<TItem> Prepend<TItem>(this IEnumerable<TItem> @this, TItem item)
- IEnumerable<TItem> Append<TItem>(this IEnumerable<TItem> @this, TItem item)
- bool TryGetNonEnumeratedCount<TItem>(this IEnumerable<TItem> source, out int count)
- IEnumerable<TItem> Zip<TFirst, TSecond, TResult>(IEnumerable<TFirst> @this, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
- IEnumerable<TSource[]> Chunk<TSource>(this IEnumerable<TSource> source, int size)
- IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
- IEnumerable<TSource> ExceptBy<TSource, TKey>(this IEnumerable<TSource> first, IEnumerable<TKey> second, Func<TSource, TKey> keySelector)
- IEnumerable<TSource> IntersectBy<TSource, TKey>(this IEnumerable<TSource> first, IEnumerable<TKey> second, Func<TSource, TKey> keySelector)
- IEnumerable<TSource> UnionBy<TSource, TKey>(this IEnumerable<TSource> first, IEnumerable<TSource> second, Func<TSource, TKey> keySelector)
- IOrderedEnumerable<T> Order<T>(this IEnumerable<T> source)
- IOrderedEnumerable<T> OrderDescending<T>(this IEnumerable<T> source)
- IEnumerable<(int Index, TSource Item)> Index<TSource>(this IEnumerable<TSource> source)
- IEnumerable<KeyValuePair<TKey, int>> CountBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
- IEnumerable<KeyValuePair<TKey, TAccumulate>> AggregateBy<TSource, TKey, TAccumulate>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, TAccumulate> seed, Func<TAccumulate, TSource, TAccumulate> func)
System.Random
- long NextInt64(this Random @this)
- long NextInt64(this Random @this, long maxValue)
- long NextInt64(this Random @this, long minValue, long maxValue)
- float NextSingle(this Random @this)
- T[] GetItems<T>(this Random @this, T[] choices, int length)
- void GetItems<T>(this Random @this, ReadOnlySpan<T> choices, Span<T> destination)
- void Shuffle<T>(this Random @this, T[] values)
- void Shuffle<T>(this Random @this, Span<T> values)
System.Reflection.Assembly
- Attribute GetCustomAttribute(this Assembly element, Type attributeType)
- T GetCustomAttribute<T>(this Assembly element)
- IEnumerable<Attribute> GetCustomAttributes(this Assembly element)
- IEnumerable<Attribute> GetCustomAttributes(this Assembly element, Type attributeType)
- IEnumerable<T> GetCustomAttributes<T>(this Assembly element)
- bool IsDefined(this Assembly element, Type attributeType)
System.Reflection.Module
- Attribute GetCustomAttribute(this Module element, Type attributeType)
- T GetCustomAttribute<T>(this Module element)
- IEnumerable<Attribute> GetCustomAttributes(this Module element)
- IEnumerable<Attribute> GetCustomAttributes(this Module element, Type attributeType)
- IEnumerable<T> GetCustomAttributes<T>(this Module element)
- bool IsDefined(this Module element, Type attributeType)
System.Reflection.MemberInfo
- Attribute GetCustomAttribute(this MemberInfo element, Type attributeType)
- Attribute GetCustomAttribute(this MemberInfo element, Type attributeType, bool inherit)
- T GetCustomAttribute<T>(this MemberInfo element)
- T GetCustomAttribute<T>(this MemberInfo element, bool inherit)
- IEnumerable<Attribute> GetCustomAttributes(this MemberInfo element)
- IEnumerable<Attribute> GetCustomAttributes(this MemberInfo element, bool inherit)
- IEnumerable<Attribute> GetCustomAttributes(this MemberInfo element, Type attributeType)
- IEnumerable<Attribute> GetCustomAttributes(this MemberInfo element, Type attributeType, bool inherit)
- IEnumerable<T> GetCustomAttributes<T>(this MemberInfo element)
- IEnumerable<T> GetCustomAttributes<T>(this MemberInfo element, bool inherit)
- bool IsDefined(this MemberInfo element, Type attributeType)
- bool IsDefined(this MemberInfo element, Type attributeType, bool inherit)
System.Reflection.ParameterInfo
- Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType)
- Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType, bool inherit)
- T GetCustomAttribute<T>(this ParameterInfo element)
- T GetCustomAttribute<T>(this ParameterInfo element, bool inherit)
- IEnumerable<Attribute> GetCustomAttributes(this ParameterInfo element)
- IEnumerable<Attribute> GetCustomAttributes(this ParameterInfo element, bool inherit)
- IEnumerable<Attribute> GetCustomAttributes(this ParameterInfo element, Type attributeType)
- IEnumerable<Attribute> GetCustomAttributes(this ParameterInfo element, Type attributeType, bool inherit)
- IEnumerable<T> GetCustomAttributes<T>(this ParameterInfo element)
- IEnumerable<T> GetCustomAttributes<T>(this ParameterInfo element, bool inherit)
- bool IsDefined(this ParameterInfo element, Type attributeType)
- bool IsDefined(this ParameterInfo element, Type attributeType, bool inherit)
System.Reflection.MethodInfo
- Delegate CreateDelegate(this MethodInfo @this, Type result)
System.String
- int GetHashCode(this string @this, StringComparison comparisonType)
- bool Contains(this string @this, string value, StringComparison comparisonType)
- bool Contains(this string @this, char value)
- bool Contains(this string @this, char value, StringComparison comparisonType)
- bool StartsWith(this string @this, char value)
- bool EndsWith(this string @this, char value)
- string Trim(this string @this, char trimChar)
- string TrimStart(this string @this, char trimChar)
- string TrimEnd(this string @this, char trimChar)
- string ReplaceLineEndings(this string @this)
- string ReplaceLineEndings(this string @this, string replacementText)
- void CopyTo(this string @this, Span<char> destination)
- bool TryCopyTo(this string @this, Span<char> destination)
- string[] Split(this string @this, char separator, StringSplitOptions options = StringSplitOptions.None)
- string[] Split(this string @this, char separator, int count, StringSplitOptions options = StringSplitOptions.None)
- string[] Split(this string @this, string separator, StringSplitOptions options = StringSplitOptions.None)
- string[] Split(this string @this, string separator, int count, StringSplitOptions options = StringSplitOptions.None)
- int IndexOf(this string @this, char value, StringComparison comparisonType)
- ReadOnlySpan<char> AsSpan(this string @this)
- ReadOnlySpan<char> AsSpan(this string @this, int start)
- ReadOnlySpan<char> AsSpan(this string @this, int start, int length)
- ReadOnlySpan<char> AsSpan(this string @this, Index startIndex)
- ReadOnlySpan<char> AsSpan(this string @this, Range range)
System.Numerics.Matrix3x2
- float GetElement(this Matrix3x2 @this, int row, int column)
- Matrix3x2 WithElement(this Matrix3x2 @this, int row, int column, float value)
- Vector2 GetRow(this Matrix3x2 @this, int index)
- Matrix3x2 WithRow(this Matrix3x2 @this, int index, Vector2 value)
- Vector2 (https://learn.microsoft.com/dotnet/api/system.numerics.matrix3x2.x) / Y / Z (extension properties)
- Matrix3x2 WithX(this Matrix3x2 @this, Vector2 value) / WithY / WithZ
- Matrix3x2 Create(...) - multiple overloads
System.Numerics.Matrix4x4
- Vector4 GetRow(this Matrix4x4 @this, int index)
- Matrix4x4 WithRow(this Matrix4x4 @this, int index, Vector4 value)
- Vector4 (https://learn.microsoft.com/dotnet/api/system.numerics.matrix4x4.x) / Y / Z / W (extension properties)
- Matrix4x4 WithX(this Matrix4x4 @this, Vector4 value) / WithY / WithZ / WithW
- Matrix4x4 Create(...) - multiple overloads
- Matrix4x4 CreateBillboardLeftHanded(...)
- Matrix4x4 CreateConstrainedBillboardLeftHanded(...)
- Matrix4x4 CreateLookAtLeftHanded(...)
- Matrix4x4 CreateLookToLeftHanded(...)
- Matrix4x4 CreateOrthographicLeftHanded(...)
- Matrix4x4 CreateOrthographicOffCenterLeftHanded(...)
- Matrix4x4 CreatePerspectiveLeftHanded(...)
- Matrix4x4 CreatePerspectiveFieldOfViewLeftHanded(...)
- Matrix4x4 CreatePerspectiveOffCenterLeftHanded(...)
- Matrix4x4 CreateViewportLeftHanded(...)
System.Numerics.Plane
System.Numerics.Quaternion
- Quaternion Zero (static property)
- float GetElement(this Quaternion @this, int index)
- Quaternion WithElement(this Quaternion @this, int index, float value)
- Quaternion Create(Vector3 vectorPart, float scalarPart)
- Quaternion Create(float x, float y, float z, float w)
System.RuntimeServices.CompilerServices.RuntimeHelpers
- T[] GetSubArray<T>(T[] array, Range range)
- int OffsetToStringData
System.Text.StringBuilder
- void Clear(this StringBuilder @this)
System.Threading.Tasks
- TaskAwaiter GetAwaiter(this Task task)
- TaskAwaiter<TResult> GetAwaiter<TResult>(this Task<TResult> task)
- ConfiguredTaskAwaitable ConfigureAwait(this Task task, bool continueOnCapturedContext)
- ConfiguredTaskAwaitable<TResult> ConfigureAwait<TResult>(this Task<TResult> task, bool continueOnCapturedContext)
System.Threading.WaitHandle
- void Dispose(this WaitHandle @this)
Installation
You can install the FrameworkExtensions.Backports package via NuGet Package Manager or the .NET CLI:
NuGet Package Manager
Install-Package FrameworkExtensions.Backports
.NET CLI
dotnet add package FrameworkExtensions.Backports
Usage
Below are some examples of how to use the features provided by this package. Note that the namespaces are kept original, so no additional using directives are needed.
Range and Index
public class Program
{
public static void Main()
{
int[] numbers = { 1, 2, 3, 4, 5 };
var slice = numbers[1..^1];
Console.WriteLine(string.Join(", ", slice)); // Output: 2, 3, 4
}
}
Lazy Initialization
public class Program
{
private static Lazy<int> lazyValue = new Lazy<int>(() => ComputeValue());
public static void Main()
{
Console.WriteLine(lazyValue.Value); // Output: Computed Value
}
private static int ComputeValue()
{
Console.WriteLine("Computed Value");
return 42;
}
}
LINQ Methods
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var max = numbers.Max();
var minBy = numbers.MinBy(n => n);
Console.WriteLine($"Max: {max}"); // Output: Max: 5
Console.WriteLine($"MinBy: {minBy}");// Output: MinBy: 1
}
}
Task Extensions
using System.Threading.Tasks;
public class Program
{
public static async Task Main()
{
Task task = Task.Delay(1000);
await task.ConfigureAwait(false);
Console.WriteLine("Task completed");
}
}
Planned Features
The goal is to make Backports compiler-complete for older targets with the same runtime functionality as modern .NET.
Test Coverage
- Add comprehensive tests for all existing polyfills
- Add tests for Memory<T>, MemoryPool<T>, ReadOnlySequence<T>, Vector128/256/512<T>
- Ensure test parity across all target frameworks (net35-net9.0)
Known Issues
- net2.0 - Hard to write unit tests for as I didn't have an nunit compatible nuget package at hand.
- netstandard2.0/2.1 test targets - These are API specifications, not runtimes. Tests compile but cannot execute directly; functionality is verified via compatible runtimes (netcoreapp3.1, net5.0+)
- .NET SDK 10.0 test platform - VSTest 18.x has compatibility issues with older .NET Core runtimes when running from CLI; Visual Studio Test Explorer handles this better
Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository.
- Create a new branch with a descriptive name.
- Make your changes.
- Remember: Everything public in here should polyfill existing Microsoft functionality and thus should be mentioned in the Readme with a link to its original documentation.
- Submit a pull request.
License
This project is licensed under the LGPL-3.0-or-later License. See the LICENSE file for details.
Acknowledgments
We appreciate the contributions of the .NET community in making this package possible.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 is compatible. net5.0-windows was computed. net6.0 is compatible. 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 is compatible. 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 is compatible. 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. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 is compatible. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net20 is compatible. net35 is compatible. net40 is compatible. net403 was computed. net45 is compatible. net451 was computed. net452 was computed. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. 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. |
-
.NETCoreApp 3.1
- System.Runtime.CompilerServices.Unsafe (>= 6.0.0)
-
.NETFramework 2.0
- No dependencies.
-
.NETFramework 3.5
- No dependencies.
-
.NETFramework 4.0
- Microsoft.Bcl (>= 1.1.10)
- Microsoft.Bcl.Async (>= 1.0.168)
-
.NETFramework 4.5
- System.Buffers (>= 4.5.1)
- System.Memory (>= 4.5.5)
- System.Numerics.Vectors (>= 4.5.0)
- System.Runtime.CompilerServices.Unsafe (>= 4.5.3)
- System.Threading.Tasks.Extensions (>= 4.5.4)
- System.ValueTuple (>= 4.5.0)
-
.NETFramework 4.8
- Microsoft.Bcl.HashCode (>= 1.1.1)
- System.Buffers (>= 4.5.1)
- System.Memory (>= 4.5.5)
- System.Numerics.Vectors (>= 4.5.0)
- System.Runtime.CompilerServices.Unsafe (>= 6.0.0)
- System.Threading.Tasks.Extensions (>= 4.5.4)
-
.NETStandard 2.0
- Microsoft.Bcl.HashCode (>= 1.1.1)
- System.Buffers (>= 4.5.1)
- System.Memory (>= 4.5.5)
- System.Numerics.Vectors (>= 4.5.0)
- System.Runtime.CompilerServices.Unsafe (>= 6.0.0)
- System.Threading.Tasks.Extensions (>= 4.5.4)
-
.NETStandard 2.1
- System.Runtime.CompilerServices.Unsafe (>= 6.0.0)
-
net5.0
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (5)
Showing the top 5 NuGet packages that depend on FrameworkExtensions.Backports:
| Package | Downloads |
|---|---|
|
FrameworkExtensions.Corlib
Extensions to the Corlib. |
|
|
FrameworkExtensions.System.Windows.Forms
Extensions to WindowsForms. |
|
|
FrameworkExtensions.PresentationCore
Extensions to WPF. |
|
|
FrameworkExtensions.System.Drawing
Extensions to System.Drawing |
|
|
FrameworkExtensions.DirectoryServices
Extensions to DirectoryServices. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0.256 | 301 | 3/2/2026 |
| 1.0.0.254 | 202 | 2/9/2026 |
| 1.0.0.250 | 191 | 2/2/2026 |
| 1.0.0.245 | 179 | 1/26/2026 |
| 1.0.0.237 | 168 | 1/19/2026 |
| 1.0.0.235 | 146 | 1/12/2026 |
| 1.0.0.231 | 183 | 1/5/2026 |
| 1.0.0.212 | 178 | 12/29/2025 |
| 1.0.0.198 | 267 | 12/22/2025 |
| 1.0.0.183 | 428 | 12/15/2025 |
| 1.0.0.167 | 499 | 11/17/2025 |
| 1.0.0.166 | 252 | 11/10/2025 |
| 1.0.0.163 | 299 | 9/29/2025 |
| 1.0.0.159 | 314 | 9/22/2025 |
| 1.0.0.158 | 313 | 9/15/2025 |
| 1.0.0.157 | 584 | 8/18/2025 |
| 1.0.0.156 | 293 | 8/4/2025 |
| 1.0.0.147 | 415 | 7/21/2025 |
| 1.0.0.142 | 1,183 | 7/7/2025 |
| 1.0.0.137 | 239 | 6/23/2025 |