結論
https://stackoverflow.com/a/29379250 に載ってる方法で、1回分の仮想関数の呼び出しコストが増えるけどGenericsの特殊化みたいなことができる。
どういうことか
↓のようなコードを書くと、 Hoge の型引数 T が int か double のときは Hoge<T>.P.Func はなんらかの値を返してくれるけど、それ以外の場合は NotSupportedException を投げるようになる。
Hoge.P は IHoge<int> か IHoge<double> にしかキャストできないので、
-
Tがintかdoubleのとき、Hoge<T>.PはHoge.Pで初期化される -
Tがそれ以外の場合はHoge.P as IHoge<T>はnullになるので、Hoge<T>.Pはnew Hoge<T>()で初期化される
というように、T が int か double のときだけ Hoge<T>.P がGenericじゃない方の Hoge で初期化されるのでこうなる。
public interface IHoge<T>
{
T Func(T value);
}
public class Hoge<T> : IHoge<T>
{
public static readonly IHoge<T> P = Hoge.P as IHoge<T> ?? new Hoge<T>();
public T Func(T value)
{
throw new NotSupportedException();
}
}
public class Hoge : IHoge<int>, IHoge<double>
{
public static readonly Hoge P = new Hoge();
public int Func(int value)
{
return value;
}
public double Func(double value)
{
return value;
}
}