Пусть есть абстрактный класс AbstractClass и класс его реализующий ExtendedClass. Абстрактный класс определяет абстрактный метод modify, который возвращает сам обьект для реализации method chaining. Тип возвращаемого обьекта — AbstractClass, так как мы не знаем какой класс будет переобределять этот абстрактный класс.
abstract class AbstractClass
{
protected int _value;
public AbstractClass setValue(int value)
{
_value = value;
return this;
}
abstract public AbstractClass modify();
public int getValue()
{
return _value;
}
}
Реализуем абстрактный метод modify:
class ExtendedClass : AbstractClass
{
public override ExtendedClass modify()
{
_value++;
return this;
}
public override ExtendedClass modifyAgain()
{
_value *= 2;
return this;
}
}
Попробуем запустить код:
ExtendedClass c = new ExtendedClass();
int value = c.setValue(42).modify().modifyAgain().getValue();
Получаем:
Ошибка 1 «ConsoleApplication1.ExtendedClass.modify()»: возвращаемый тип должен быть «ConsoleApplication1.AbstractClass» для соответствия переопределенному члену «ConsoleApplication1.AbstractClass.modify()» D:\projects\ConsoleApplication1\ExtendedClass.cs 10 39 ConsoleApplication1
Понимаю почему так происходит, но не понимаю как сделать method chaining в C#. Может есть способ сказать «этот класс» при указании типа возвращаемого значения в методе?
PS: решение:
abstract class AbstractClass<T> where T: AbstractClass<T>
{
protected int _value;
public T setValue(int value)
{
_value = value;
return (T) this;
}
abstract public T modify();
public int getValue()
{
return _value;
}
}
class ExtendedClass : AbstractClass<ExtendedClass>
{
public override ExtendedClass modify()
{
_value++;
return this;
}
public override ExtendedClass modifyAgain()
{
_value *= 2;
return this;
}
}