プリミティブ型のGenerics

http://d.hatena.ne.jp/akiramei/20040710#p3
プリミティブ型に対してOperatorが使えるようにとの要望があがっていましたが、今のところ投票は7つで、あんま必要とされていない感じです。多分、採用されない気がするので自分でプリミティブ型に対するジェネリックな関数を書くとしたらどーすればいいか、色々模索してみました。例えば、delegateを使った実装。

using System;
using System.Collections.Generic;

public delegate T UnaryOp<T>(int value);
public delegate T BinaryOp<T>(T lhs, T rhs);

public struct Operator<T>
{
    public UnaryOp<T> V;
    public BinaryOp<T> Add;
    public BinaryOp<T> Subtract;
    public BinaryOp<T> Multiply;
    public BinaryOp<T> Divide;

    public Operator(UnaryOp<T> v, BinaryOp<T> add, BinaryOp<T> sub, BinaryOp<T> mul, BinaryOp<T> div)
    {
        V = v;
        Add = add;
        Subtract = sub;
        Multiply = mul;
        Divide = div;
    }
}

public struct Operators
{
    private static Operator<int> iOp;
    private static Operator<double> dOp;

    static Operators()
    {
        iOp = new Operator<int>(
            delegate(int v) { return v; },
            delegate(int x, int y) { return x + y; },
            delegate(int x, int y) { return x - y; },
            delegate(int x, int y) { return x * y; },
            delegate(int x, int y) { return x / y; });
        dOp = new Operator<double>(
            delegate(int v) { return v; },
            delegate(double x, double y) { return x + y; },
            delegate(double x, double y) { return x - y; },
            delegate(double x, double y) { return x * y; },
            delegate(double x, double y) { return x / y; });
    }

    public static Operator<int> Int32
    {
        get { return iOp; }
    }

    public static Operator<double> Double
    {
        get { return dOp; }
    }
}

class Program
{
    // 多項式の計算
    static T Horner<T>(Operator<T> op, T x, T a)
    {
        T p = op.V(0);
        int n = a.Length - 1;
        p = a[n];
        for (int i = n - 1; i >= 0; i--)
            p = op.Add(op.Multiply(p, x), a[i]);
        return p;
    }

    static void Main(string args)
    {
        int a1 = new int { 1, 2, 3, 4, 5 };
        double a2 = new double { 1.1, 2.2, 3.3, 4.4, 5.5 };
        // f(x) = 5x^4 + 4x^3 + 3x^2 + 2x + 1
        // f(1) = 15
        Console.WriteLine(Horner<int>(Operators.Int32, 1, a1));
        // f(x) = 5.5x^4 + 4.4x^3 + 3.3x^2 + 2.2x + 1.1
        // f(5.0) = 4082.1
        Console.WriteLine(Horner<double>(Operators.Double, 5.0, a2));

        Console.ReadLine();
    }
}
/* 結果
15
4082.1*/

OperatorのコンストラクタでちまちまAnonymous Methodを渡しているところがイマイチですし、パフォーマンスも悪そうな予感。(^^; なんか上手い方法は無いかなぁ。