ネタ元>あらあらあら
C#には同じインターフェースを持たない同士でのジェネリックが定義できないという
多分、C#2.0が発表されてからずっと言われ続けただろう話題ですね。
ということで、ちょっとがんばって複素数クラスを作ってみました。
public class Complex<T>{
public T re { get; set; }
public T im { get; set; }
static public Func<T, T, T> add { get; set; }
static public Func<T, T, T> sub { get; set; }
static public Func<T, T, T> multi { get; set; }
public static Complex<T> operator +(Complex<T> lft, Complex<T> rgt){
return new Complex<T>(add(lft.re, rgt.re), add(lft.im, rgt.im));
}
public static Complex<T> operator -(Complex<T> lft, Complex<T> rgt){
return new Complex<T>(sub(lft.re, rgt.re), sub(lft.im, rgt.im));
}
public static Complex<T> operator *(Complex<T> lft, Complex<T> rgt){
return new Complex<T>(sub(multi(lft.re, rgt.re), multi(lft.im, rgt.im)),
add(multi(lft.re, rgt.im), multi(lft.im, rgt.re)));
}
public override string ToString(){
return "("+re + "+" + im + "i)";
}
public Complex(T re, T im){
this.re = re;
this.im = im;
}
public static void SetFunc(Func<T, T, T> add, Func<T, T, T> sub, Func<T, T, T> multi){
Complex<T>.add = add;
Complex<T>.sub= sub;
Complex<T>.multi = multi;
}
}
そして、こうやって使います。
static void Main(string[] args){
Complex<float>.SetFunc((x, y) => x + y, (x, y) => x - y, (x, y) => x * y);
Complex<float> a = new Complex<float>(5.0f, 3.0f);
Complex<float> b = new Complex<float>(2.0f, 1.0f);
var c = a + b;
var d = a - b;
var e = a * b;
Console.WriteLine(a + " + " + b + " = " + c);
Console.WriteLine(a + " - " + b + " = " + d);
Console.WriteLine(a + " * " + b + " = " + e);
}
<実行結果>
(5+3i) + (2+1i) = (7+4i)
(5+3i) - (2+1i) = (3+2i)
(5+3i) * (2+1i) = (7+11i)
ここで、addにあたる部分をoperator +の名前を持ち、Func<T, T, T>の形でstaticなものを探し出して
自動的に定義してくれればいいんですけどね~。
リフレクション使ってうまいこと出来ないかなぁ…。
public class Complex<T>
where
static T oprator + (T, T),
static T oprator - (T, T),
static T oprator * (T, T){
<中略>
}
こんな構文ができるようにしてほしいです、ほんと。