私は次のものを持っています。できます。動的な使用を避け、コードが型の数で O(n^2) になるのを避ける方法でそれを行いたいです。私が認識している標準的な二重ディスパッチ ソリューションでは、タイプ A、B、C、D のそれぞれに O(n) コードがあり、全体として O(n^2) になります。
それを行うための正気の方法はありますか?
public class P {}
public class A: P {}
public class B: P {}
public class C: P {}
public class D: P {}
public class DynamicDispatchLowPriorityMethods
{
// The superclass is to avoid a runtime error when calling Multi(b, a).
// Without something like this, the call is ambiguous.
protected string _Output {get;set;}
public DynamicDispatchLowPriorityMethods()
{
}
public void Multi(P x, P y) {
_Output += "PP ";
}
public void Multi(B x, P y) {
_Output += "bP ";
}
}
[TestFixture()]
public class DynamicDispatch: DynamicDispatchLowPriorityMethods
{
public void Multi(A x, A y) {
_Output += "aa ";
}
public void Multi(A x, P y) {
_Output += "aP ";
}
public void Multi(P x, A y) {
_Output += "Pa ";
}
public void Multi(B x, B y) {
_Output += "bb ";
}
public void Multi(C x, C y) {
_Output += "cc ";
}
public void Multi(D x, D y) {
_Output += "dd ";
}
public void Multi(B x, D y) {
_Output += "bd ";
}
public void DynamicMulti(P x, P y) {
this.Multi((dynamic)x, (dynamic)y);
}
[Test()]
public void TestDynamicDispatch()
{
_Output = "";
P a = new A ();
P b = new B ();
P c = new C ();
P d = new D ();
this.DynamicMulti(a, a);
this.DynamicMulti(a, b);
this.DynamicMulti(a, c);
this.DynamicMulti(a, d);
_Output += "\n";
this.DynamicMulti(b, a);
this.DynamicMulti(b, b);
this.DynamicMulti(b, c);
this.DynamicMulti(b, d);
_Output += "\n";
this.DynamicMulti(c, a);
this.DynamicMulti(c, b);
this.DynamicMulti(c, c);
this.DynamicMulti(c, d);
_Output += "\n";
this.DynamicMulti(d, a);
this.DynamicMulti(d, b);
this.DynamicMulti(d, c);
this.DynamicMulti(d, d);
CommonDebug.WriteLine(_Output);
}
}
出力は次のとおりです。
aa aP aP aP
Pa bb bP bd
Pa PP cc PP
Pa PP PP dd
背景については、ダブルディスパッチの代替案に関するこの質問を参照してください。