Generic math (overview), generic attributes (when relevant)
Emulate generic math without modern features: pass an ops-provider or delegates, constrain types carefully, and simulate "generic attributes" via Type parameters.
Generic math on C# 6
Goal: Write numeric algorithms generically on C# 6.
- No static abstract operators on T
- Workarounds: ops-provider interface or small delegates
- For annotations, use attributes with Type parameters
Ops-provider pattern
Provide Zero and Add via an interface. The generic algorithm calls those methods instead of using + on T.
using System;
using System.Collections.Generic;
public interface INumericOps<T>
{
T Zero { get; }
T Add(T a, T b);
}
public sealed class IntOps : INumericOps<int>
{
public int Zero { get { return 0; } }
public int Add(int a, int b) { return a + b; }
}
public sealed class DoubleOps : INumericOps<double>
{
public double Zero { get { return 0.0; } }
public double Add(double a, double b) { return a + b; }
}
public class Program
{
static T Sum<T>(IEnumerable<T> items, INumericOps<T> ops)
{
T acc = ops.Zero;
foreach (T x in items) acc = ops.Add(acc, x);
return acc;
}
public static void Main(string[] args)
{
int s1 = Sum(new int[] {1,2,3}, new IntOps());
double s2 = Sum(new double[] {1.5, 2.0}, new DoubleOps());
Console.WriteLine("Sum int = " + s1);
Console.WriteLine("Sum double = " + s2);
}
}
All lessons in this course
- unmanaged, notnull, new() (C# 6 emulation)
- Generic math (overview), generic attributes (when relevant)
- Reusable generic utilities