C++だとこんなことができますよね
#include <iostream>
template<class T> class Base {
protected:
const char* p_;
public:
Base(const char* p) : p_(p) {}
void func() { static_cast(this)->foo(); }
};
class Derived : public Base<Derived> {
public:
Derived(const char* p) : Base<Derived>(p) {}
void foo() { std::cout << p_ << std::endl; }
};
int main()
{
Derived("Hello, C++").func();
}
DerivedクラスはBase<Derived>クラスの派生クラスになっているわけです。
このような記述をすることでBaseクラスは未だ知らないDerivedクラスの仮想関数ではない任意のメンバをアクセスできます。
同じことをC#でやろうとすると…
namespace Program {
public class Base<T> {
protected string str_;
public Base(string str) { str_ = str; }
public void func() { ((T) this).foo(); }
}
public class Derived : Base<Derived> {
public Derived(string str) : base(str) {}
public void foo() { System.Console.WriteLine(str_); }
static void Main() {
(new Derived("Hello, C#")).func();
}
}
}
crtp.cs(5,31): error CS0030: 型 'Program.Base<T>' を型 'T' に変換できません。
と言われてしまう。コンパイル時に解決できそうなんだけど…
んで書きなおした。
namespace Program {
public abstract class Base<T> {
protected string str_;
public Base(string str) { str_ = str; }
public void func() { foo(); }
public abstract void foo();
}
public class Derived : Base<Derived> {
public Derived(string str) : base(str) {}
public override void foo() { System.Console.WriteLine(str_); }
static void Main() {
(new Derived("Hello, C#")).func();
}
}
}
意味ねぇorz
因みにC#をコケにするつもりはありません。それどころか最近ちょっとC#好きになってきてます
このころより考えが進歩したかなw