mayhem
@mayhem

Method chaining перегруженных методов в c#?

Пусть есть абстрактный класс 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;
    }
}
  • Вопрос задан
  • 3230 просмотров
Пригласить эксперта
Ответы на вопрос 1
Dzuba
@Dzuba
Во-первых, не понимаю зачем делать ExtendedClass возвращаемым типом в реализации метода modify(). Это не переопределение метода, а ошибка.
Делайте так:
class ExtendedClass : AbstractClass
{
    public override AbstractClass modify()
    {
         _value++;
        return this;
    }
}
Все будет работать, как вами и задумано.

Во-вторых, отвечу на ваш вопрос. Существует способ указать тип возвращаемого значения в методе. Это можно сделать при помощи generic'ов: generic-методов или generic-типов. Но в данном случае, никакой необходимости в этом нет.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы