基本構造:
public abstract class Base<T> where T : Base<T>
{
public T Original { get; private set; }
public abstract bool Changed(T o);
public bool Changed()
{
return this.Changed(Original);
}
}
public class DerivedA : Base<DerivedA>
{
public override bool Changed(DerivedA o)
{
throw new NotImplementedException();
}
}
public class DerivedB : Base<DerivedB>
{
public override bool Changed(DerivedB o)
{
throw new NotImplementedException();
}
}
短所(読みやすさ)はありますが、問題は古典的な動物/犬/猫の意味での型保護ではなく、コード共有であるため、この場合は正しい選択になる可能性があります。
このシナリオを回避するには:
public class DerivedC : DerivedB
{
}
new DerivedB().Changed(new DerivedC()); // compiles
あなたは封印することができますDerivedB。
または、狂気を続けることもできます(これはお勧めしません。間違いなく、このレベルを超えてはいけません):
public abstract class DerivedE<T> : Base<DerivedE<T>> where T : DerivedE<T>
{
}
public class DerivedF : DerivedE<DerivedF>
{
}
public class DerivedG : DerivedE<DerivedG>
{
}
new DerivedF().Changed(new DerivedG()); // does not compile
new DerivedF().Changed(new DerivedF()); // does compile
このhttp://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspxを参照してください。その記事からインスピレーションを得ました。彼は短所と長所について議論します。
編集:コメントに従って調整されたクリーンアップ