Хорошо, я неправильно понял вопрос. Я думал, что OP действительно хочет переопределить метод. Очевидно, нет, поэтому дженерики - это путь вперед:
public abstract class Base<T> where T : Base<T>
{
public T Method()
{
return (T) (object) this;
}
}
public class Derived1 : Base<Derived1>
{
}
Есть еще актеры, но, к сожалению, это неизбежно, насколько я знаю. Вы почти наверняка захотите проверить это и в конструкторе:
public Base()
{
if (this as T == null)
{
// throw some exception
}
}
Это ужасно, но это сработает ... и безобразие ограничено базовым классом.
Оригинальный ответ
Один из способов сделать это - поместить Method
в общий интерфейс и реализовать его явно:
public interface IFoo<T> {
T Method();
}
public abstract class Base : IFoo<Base>
{
Base IFoo<Base>.Method()
{
return this;
}
}
public class Derived1 : IFoo<Derived1>
{
public Derived1 Method()
{
// If you need to call the base version, you'll
// need ((IFoo<Base>)this).Method()
return this;
}
}
Это нехорошо, но это сработало бы ... там, где это возможно, я думаю, я бы старался избегать этого, если честно. (И да, я сталкивался с подобными ситуациями при реализации буферов протокола. Это раздражает.)