using System.Runtime.CompilerServices;
private interface IMath<T> {
internal T Add (T value1, T value2);
internal T Negate (T value);
private class Math<T> : IMath<T> {
internal static readonly IMath<T> P = Math.P as IMath<T> ?? new Math<T>();
T IMath<T>.Add (T a, T b) => NoSupport();
T IMath<T>.Negate (T a) => NoSupport();
private static T NoSupport ([CallerMemberName] string op = "") =>
throw new NotSupportedException($"{op} not supported for type {typeof(T).Name}.");
private class Math : IMath<int>, IMath<float> {
internal static Math P = new Math();
int IMath<int>.Add (int a, int b) => a + b;
int IMath<int>.Negate (int value) => -value;
float IMath<float>.Add (float a, float b) => a + b;
float IMath<float>.Negate (float value) => -value;
static T Negate <T> (T value) => Math<T>.P.Negate(value);
public static void Main()
Console.WriteLine(Negate(42));
Console.WriteLine(Negate(3.0f));
Console.WriteLine(Negate(2.0));