何も考えずに
とりあえず考えなしに、素直に制約インターフェスを書いてみる。
///Four Rule Of Arithmetic -able public interface IFROAble { T Add(T left, T right); T Substract(T left, T right); T Multiply(T left, T right); T Divide(T left, T right); T Negate(T value); }
使ってみる。
static T Sum(params T[] values) where T : IFROAble { if (values == null) throw new ArgumentNullException("values"); T sum = default(T); foreach (T value in values) { sum = sum.Add(sum, value); } return sum; }
あれ、T を演算対象の型としてみると、この制約に出てくる T は実装を持った型じゃないといけないから T では耐えられない。
と、ここで数十秒考えたが、素直に
static T Sum(params T[] values) where I : IFROAble { if (values == null) throw new ArgumentNullException("values"); I fra = default(I); T sum = default(T); foreach (T value in values) { sum = fra.Add(sum, value); } return sum; }
と Type と Implementation を別個で受け取るように改めた。
あまり省略しまくった名称は好きじゃないのだが、頭文字をとって T, I とした。
そして使用する。
class Int32FROAImplements : IFROAble{ public int Add(int left, int right) { return left + right; } public int Substract(int left, int right) { return left - right; } // : // :たっぷり略 // : } public static void Main() { Console.WriteLine(Sum (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); Console.WriteLine( Sum (0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)); }
とりあえず問題なく動作するものができた。