Skip to content

Instantly share code, notes, and snippets.

@doubleday
Last active October 24, 2025 22:51
Show Gist options
  • Select an option

  • Save doubleday/16d9b98fc346ccda88d03c289df03574 to your computer and use it in GitHub Desktop.

Select an option

Save doubleday/16d9b98fc346ccda88d03c289df03574 to your computer and use it in GitHub Desktop.
Allocation-free generic conversions
using System.Numerics;
var variant = new Variant("42");
int i = variant.ConvertTo<int>();
float floatSum = variant.Add(10.0f);
int intSum = variant.Add(8);
double doubleProduct = variant.Multiply(2.5);
decimal decimalSum = variant.Add(100m);
static class GenericMath
{
public static T Add<T, TVariant>(this TVariant value, T number)
where TVariant : struct, IConvertible<T>
where T : INumber<T>
=> value.Convert() + number;
public static T Multiply<T, TVariant>(this TVariant value, T number)
where TVariant : struct, IConvertible<T>
where T : INumber<T>
=> value.Convert() * number;
public static T Subtract<T, TVariant>(this TVariant value, T number)
where TVariant : struct, IConvertible<T>
where T : INumber<T>
=> value.Convert() - number;
public static T Divide<T, TVariant>(this TVariant value, T number)
where TVariant : struct, IConvertible<T>
where T : INumber<T>
=> value.Convert() / number;
}
static class Conversions
{
public static TTo ConvertTo<TTo>(this IConvertible<TTo> from)
=> from.Convert();
}
interface IConvertible<out TTo>
{
TTo Convert();
}
readonly struct Variant(string val) : IConvertible<int>, IConvertible<float>, IConvertible<double>, IConvertible<decimal>
{
int IConvertible<int>.Convert() => Convert.ToInt32(val);
float IConvertible<float>.Convert() => Convert.ToSingle(val);
double IConvertible<double>.Convert() => Convert.ToDouble(val);
decimal IConvertible<decimal>.Convert() => Convert.ToDecimal(val);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment