2009年5月10日日曜日

C#のbase.base

C#のbase.base....について調べてみました。
結局はできないみたい。
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
D d = new D();
C c = new C();
B b = c;
A a = c;

string s01 = a.f(); //="C"
string s02 = b.f(); //="C"
string s03 = c.f(); //="C"

string s04 = ((B)b).f(); //="C" キャストを明示してもダメ
string s05 = ((A)a).f(); //="C" 同上
string s06 = (c as B).f(); //="C" このキャストもダメ
string s07 = d.f(); //="C" base.f()はできるけどbase.base.f()は書けない

D1 d1 = new D1();
C1 c1 = new C1();
B1 b1 = c1;
a = c1;
string s11 = a.f(); //=A" この時点で期待外れ
string s12 = b1.f();//="B1" 以下はどうでもいいや。
string s13 = c1.f();//="C1"
string s14 = ((B1)a).f();//="B1"
string s15 = ((C1)a).f();//="C1"
string s16 = ((A)b1).f();//="A"
string s17 = d1.f(); //="C1"

C21 c21 = new C21();
C22 c22 = new C22();

string s21 = c21.f(); //="A2" 期待どおりだがbaseクラス作成時にはをこんな風には作らない...
string s22 = c22.f(); //="B2"

a = c;
b = c;
string s31 = a.g();//="C"拡張メソッド内ではbaseは使えない...
string s32 = b.g();//同上

//型変換エラーが発生するためコメントアウト
//A aa = ((A)Convert.ChangeType(c, Type.GetType("ConsoleApplication3.A")));

string[] strl = { "aa", "bb" };
}

}

//オーバーライド
class A { public virtual string f() { return "A"; } }
class B : A { public override string f() { return "B"; } }
class C : B { public override string f() { return "C"; } }
class D : C { public override string f() { return base.f(); } }

//ある意味オーバーロード?
class B1 : A { public new string f() { return "B1"; } }
class C1 : B1 { public new string f() { return "C1"; } }
class D1 : C1 { public new string f() { return base.f(); } }

//ベースの呼び出しを継承クラスから呼び出せるようにしたもの
//ただA2を作る時点でこんなつくりにすることは考えられないなあ
class A2
{
public virtual string f() { return A2f(); }
protected string A2f() { return "A2"; }
}
class B2 : A2 { public override string f() { return "B2"; } }
class C21 : B2 { public override string f() { return A2f(); } }
class C22 : B2 { public override string f() { return base.f(); } }

//C#3.0からの拡張メソッド g
internal static class ClassUtility { internal static string g(this A a) { return a.f(); } }

}

0 件のコメント: