Skip to main content

FastGenericNew by Boring3 Nyrest

Nuget / site data

Nuget GitHub last commit GitHub Repo stars

Details

Info

info

Name: FastGenericNew

Configurable Source Generator of FastGenericNew Minimum required: .NET Standard 2.0 & C# 8.0 The ultimate fast alternative to Activator.CreateInstance

Up to 50x faster than Activator.CreateInstance Generic Parameters Support Non-Public Constructor Support No Generic Constraints TryGetValue-like TryFastNew API Link Mode PublishTrimmed Support C# 8 Nullable Support C# 10 Parameterless struct constructors Support (Both invokes or not)

Author: Boring3 Nyrest

NuGet: https://www.nuget.org/packages/FastGenericNew.SourceGenerator/

You can find more details at https://github.com/Nyrest/FastGenericNew

Source : https://github.com/Nyrest/FastGenericNew

Original Readme

note

✨ Features

  • ✔️ The best CreateInstance ever

    • Up to 50x faster than Activator.CreateInstance
    • Generic Parameters Support
    • Zero boxing/unboxing
    • TryGetValue-like TryFastNew API
    • Link Mode PublishTrimmed Support
    • Non-Public Constructor Support
    • No Generic Constraints
    • Compatible with .NET Standard 2.0
    • Multiple backend implementations.
    • Heavily tested on Win/Mac/Linux
  • 🪛 Modern Compiler Integration

    • Source Generator v2 (Incremental Generator)
    • Highly Configurable (Props)
    • Multi-threaded Generation
  • 🔥 Lastest C#/.NET Features Support

🔧 Installation

You should only use one of them

Pre-Compiled Version

dotnet add package FastGenericNew --version 3.1.0-preview1
<ItemGroup>
<PackageReference Include="FastGenericNew" Version="3.1.0-preview1" />
</ItemGroup>

SourceGenerator Version

dotnet add package FastGenericNew.SourceGenerator --version 3.1.0-preview1
<ItemGroup>
<PackageReference Include="FastGenericNew.SourceGenerator" Version="3.1.0-preview1" />
</ItemGroup>

SourceGeneratorV2 requires

.NET Standard 2.0 or above
C# 8.0 or above
Roslyn 4.0.1 or above
Modern IDE (Optional) [VS2022, Rider, VSCode]

📖 Examples

using FastGenericNew;

// Simply replace 'Activator' to 'FastNew'
var obj = FastNew.CreateInstance<T>();

// With parameter(s)
var obj2 = FastNew.CreateInstance<T, string>("text");
var obj3 = FastNew.CreateInstance<T, string, int>("text", 0);

// Try pattern
// NOTE: Try pattern will only check the constructor could be called (exist & callable)
// It will not catch or handle any exceptions thrown in the constructor.
if (FastNew.TryCreateInstance<T, string>("arg0", out T result));
{
// ...
}

Notes

With .NET Framework, Activator.CreateInstance<T>() invokes the parameterless constructor of ValueType if
the constraint is where T : new() but appears to ignore the parameterless constructor if the constraint is where T : struct.
But FastNew.CreateInstance<T>() will always invoke the parameterless constructor if it's available.

If you don't want to invoke the parameterless constructor of ValueType.
Consider to use FastNew.NewOrDefault<T>() which will never invoke the parameterless constructor of ValueType

🚀 Benchmark

Environment

BenchmarkDotNet=v0.13.1, OS=Windows 10.0.22000
AMD Ryzen 9 3900X, 1 CPU, 24 logical and 12 physical cores
.NET SDK=6.0.200-preview.22055.15
[Host] : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
.NET 5.0 : .NET 5.0.14 (5.0.1422.5710), X64 RyuJIT
.NET 6.0 : .NET 6.0.2 (6.0.222.6406), X64 RyuJIT
.NET Framework 4.8 : .NET Framework 4.8 (4.8.4470.0), X64 RyuJIT

Reference Types

Benchmark Result of Reference Types

Value Types

Benchmark Result of Value Types

📜 License

FastGenericNew is licensed under the MIT license.

About

note

Creating instances fast. As generator show source code. Otherwise could be a dll

How to use

Example ( source csproj, source files )

This is the CSharp Project that references FastGenericNew

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FastGenericNew.SourceGenerator" Version="3.1.0-preview1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

Generated Files

Those are taken from $(BaseIntermediateOutputPath)\GX

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by FastGenericNew.SourceGenerator
// Please do not modify this file directly
// <auto-generated/>
//------------------------------------------------------------------------------
#nullable enable
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Reflection.Emit;
using System.ComponentModel;

namespace @FastGenericNew
{
public static partial class FastNew{

/// <summary>
/// <para>Create an instance of <typeparamref name="T" /></para>
/// <para>Returns <c><see langword="new" /> <typeparamref name="T" />()</c> if <typeparamref name="T"/> is a <see cref="ValueType"/>(struct)</para>
/// <para>This <b>CAN</b> call the Parameterless Constructor of the <see cref="ValueType"/>(struct)</para>
/// </summary>
/// <typeparam name="T">The type to create.</typeparam>
/// <returns>A new instance of <typeparamref name="T" /></returns>
/// <remarks>
/// Equivalent to <c><see langword="new" /> <typeparamref name="T" />()</c> for both Reference Types and Value Types
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T>()
{
#if NETFRAMEWORK
return global::@FastGenericNew.FastNew<T>.CompiledDelegate();
#else
return typeof(T).IsValueType
? System.Activator.CreateInstance<T>() // This will be optimized by JIT
: global::@FastGenericNew.FastNew<T>.CompiledDelegate();
#endif
}
/// <summary>
/// Create an instance of <typeparamref name="T" /> <br/>
/// Returns <c><see langword="default" />(<typeparamref name="T" />)</c> if <typeparamref name="T"/> is a <see cref="ValueType"/>(struct) <br/>
/// This <b>WILL NOT</b> call the Parameterless Constructor of the <see cref="ValueType"/>(struct)
/// </summary>
/// <typeparam name="T">The type to create.</typeparam>
/// <returns>A new instance of <typeparamref name="T" /></returns>
/// <remarks>
/// For reference types, equivalent to <c><see langword="new" /> <typeparamref name="T" />()</c> <br/>
/// For value types, equivalent to <c><see langword="default" />(<typeparamref name="T" />)</c>
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T NewOrDefault<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T>()
{
#if NETFRAMEWORK
return global::@FastGenericNew.FastNew<T>._isValueTypeT
#else
return typeof(T).IsValueType
#endif
? default(T)! // This will never be null since T is a ValueType
: FastNew<T>.CompiledDelegate();
}
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0>(TArg0 p0) =>
global::@FastGenericNew.FastNew<T, TArg0>.CompiledDelegate(p0);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1>(TArg0 p0, TArg1 p1) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1>.CompiledDelegate(p0, p1);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2>(TArg0 p0, TArg1 p1, TArg2 p2) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2>.CompiledDelegate(p0, p1, p2);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3>.CompiledDelegate(p0, p1, p2, p3);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4>.CompiledDelegate(p0, p1, p2, p3, p4);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5>.CompiledDelegate(p0, p1, p2, p3, p4, p5);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6, TArg7 p7) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6, p7);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6, TArg7 p7, TArg8 p8) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6, p7, p8);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6, TArg7 p7, TArg8 p8, TArg9 p9) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6, TArg7 p7, TArg8 p8, TArg9 p9, TArg10 p10) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6, TArg7 p7, TArg8 p8, TArg9 p9, TArg10 p10, TArg11 p11) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6, TArg7 p7, TArg8 p8, TArg9 p9, TArg10 p10, TArg11 p11, TArg12 p12) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6, TArg7 p7, TArg8 p8, TArg9 p9, TArg10 p10, TArg11 p11, TArg12 p12, TArg13 p13) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6, TArg7 p7, TArg8 p8, TArg9 p9, TArg10 p10, TArg11 p11, TArg12 p12, TArg13 p13, TArg14 p14) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14);
public static T CreateInstance<
#if NET5_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15>(TArg0 p0, TArg1 p1, TArg2 p2, TArg3 p3, TArg4 p4, TArg5 p5, TArg6 p6, TArg7 p7, TArg8 p8, TArg9 p9, TArg10 p10, TArg11 p11, TArg12 p12, TArg13 p13, TArg14 p14, TArg15 p15) =>
global::@FastGenericNew.FastNew<T, TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15>.CompiledDelegate(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15);
}
}

Usefull

Download Example (.NET C# )

Share FastGenericNew

https://ignatandrei.github.io/RSCG_Examples/v2/docs/FastGenericNew

In the same category (EnhancementClass) - 25 other generators

ApparatusAOT

AspectGenerator

CommonCodeGenerator

DudNet

Enhanced.GetTypes

HsuSgSync

Immutype

Ling.Audit

Lombok.NET

M31.FluentAPI

MemoryPack

Meziantou.Polyfill

Microsoft.Extensions.Logging

Microsoft.Extensions.Options.Generators.OptionsValidatorGenerator

Microsoft.Interop.JavaScript.JSImportGenerator

OptionToStringGenerator

QueryStringGenerator

RSCG_Decorator

RSCG_UtilityTypes

StaticReflection

SyncMethodGenerator

System.Runtime.InteropServices

System.Text.RegularExpressions

TelemetryLogging

ThisClass