Home

Awesome

<center><h1 align="center">UnionType</h1></center> <div align="center">
Powerful, low consumption, and highly scalable type for c#.

.NET Build codecov

</div>

What is this

It provide an union type struct, for strongly typed c# language.

How to implement

Use Memory mask to make struct has 16(maximum primary type bytes)+1(type store) bytes, it can be store primary types.

Object store use GCHandle to pin memory.

Samples

samples/UnionType.Sample

implicit cast in any time

using System;
using UnionType;

internal class Program
{
    static void Main()
    {
        UnionValue a = 123;
        int b = a;//123
    }
}

You can use navite point or ref

using System;
using UnionType;

internal class Program
{
    unsafe static void Main()
    {
        UnionValue a = 123;
        Console.WriteLine(*a.ToPointer<int>());//Print 123
    }
}

It is not a read-only type

using System;
using UnionType;

internal class Program
{
    static void Main()
    {
        var uv = (UnionValue)123;
        Inc(ref uv);
        Console.WriteLine(uv.@int);//Print 124
    }
    private static void Inc(ref UnionValue value)
    {
        value.@int++;
    }
}

It can accommodate all basic types

It can fast alloc decimal from number

Performace is alloc decimal benchmark

using System;
using UnionType;

internal class Program
{
    static void Main()
    {
        var uv = UnionValue.FromAsDecimal(123);
        Console.WriteLine(uv.@decimal);//123
    }
}

Implement p type interface(No .NET 7)

Space saving

using System;
using System.Runtime.CompilerServices;
using UnionType;

internal class Program
{
    static void Main()
    {
        Console.WriteLine(Unsafe.SizeOf<UnionValue>());//In .NET7.0 print 24, other print 17
    }
}

Able to operate

using System;
using UnionType;

internal class Program
{
    static void Main()
    {
        UnionValue a = 123;
        UnionValue b = 456;

        var result = a + b;
        Console.WriteLine(result.ToString());//579
    }
}

Supports

Integer will become long, floating point will become decimal

Can compare

using System;
using UnionType;

internal class Program
{
    static void Main()
    {
        UnionValue a = 123;
        var b = 456;
        Console.WriteLine(a > b);//False
        Console.WriteLine(a < b);//True
    }
}

Supports

Can store object(weak ref)

using System;
using UnionType;

internal class Program
{
    static void Main()
    {
        var obj = new Program();
        var uv = new UnionValue { Object = obj };
        Console.WriteLine(uv.TypeNameString);//Program, rsa2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
        Console.WriteLine(uv.Object);//Program
    }
}

No box, raw type, can box if you need

using System;
using UnionType;

internal class Program
{
    static void Main()
    {
        var uv = UnionValue.FromAsDecimal(123);
        Console.WriteLine(uv.Box());//123
    }
}

FromObject or raw type

using System;
using UnionType;

internal class Program
{
    static void Main()
    {
        var uv = UnionValue.FromObject(123);//Fast
        Console.WriteLine(uv.Box());//123
        uv = UnionValue.FromObject((object)123);
        Console.WriteLine(uv.Box());//123
    }
}

I use raw point copy!

https://github.com/Cricle/UnionType/blob/eff150cb9a216506ea8d6b3968101165251e431b/src/UnionType/UnionValueCreator.cs#L108

In serialize case.(Can see UnionValueToBytesHelperTest.cs)

Performace


BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.2364)
Intel Core i5-9400F CPU 2.90GHz (Coffee Lake), 1 CPU, 6 logical and 6 physical cores
.NET SDK=7.0.100
  [Host]     : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
  DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2


MethodCountMeanErrorStdDevRatioRatioSDAllocatedAlloc Ratio
Decimal500136.3 ns0.37 ns0.33 ns1.000.00-NA
Union500136.5 ns0.47 ns0.42 ns1.000.00-NA
Box500136.5 ns0.66 ns0.62 ns1.000.00-NA
BigInteger500912.7 ns3.84 ns3.59 ns6.700.03-NA
Decimal50000001,290,235.7 ns2,928.91 ns2,596.40 ns1.000.00-NA
Union50000001,291,152.6 ns4,300.97 ns3,812.70 ns1.000.001 BNA
Box50000001,291,088.1 ns3,581.48 ns2,990.70 ns1.000.001 BNA
BigInteger50000009,026,300.8 ns10,061.51 ns8,919.27 ns7.000.018 BNA