@L1L1L2

Как обработать производный класс аргументов в делегате принимающем базовый класс аргументов?

Я пытаюсь написать библиотеку для нахождения экстремума произвольной функции n переменных.

Для начала я пытаюсь задать проблемную функцию и параметры задачи в классе:

public abstract class Problem
    {
        public delegate double FunctionDelegate(FunctionArgs args);
        public FunctionDelegate Function;
        public SearchArea SearchArea;
    }

public abstract class FunctionArgs
    { }

public class SearchArea
    {
        public double AreaStart;
        public double AreaEnd;
        public SearchArea(double areaStart, double areaEnd)
        {
            AreaStart = areaStart;
            AreaEnd = areaEnd;
        }
    }


Я бы хотел задавать конкретную проблему в виде наследника от Problem, примерно так:
class ConcreteArgs : FunctionArgs
    {
        public double x1;
        public double x2;
    }

public class ConcreteProblem : Problem
    {
         public class ConcreteProblem : Problem
    {
        public double Func(ConcreteArgs args)
        {
            return 100 * Math.Pow(Math.Pow(args.x1, 2) - Math.Pow(args.x2, 2), 2) + Math.Pow(1 - args.x1, 2);
        }

        public ConcreteProblem()
        {
            //Вот здесь ошибка несоответствия делегату
            Function = Func;
            SearchArea = new SearchArea(-5.12, 5.12);
        }
    }
    }


Однако, базовый делегат не способен обрабатывать наследников от FunctionArgs. Как это исправить?

upd
Идея в том, что пользователь библиотеки пишет свою ConcreteProblem и аргументы
  • Вопрос задан
  • 62 просмотра
Пригласить эксперта
Ответы на вопрос 1
gdt
@gdt
Программист
Я вижу два варианта - простой и правильный.
Простой состоит в том, что все ваши методы будут иметь сигнатуры базового класса, и в каждом наследнике вы будете кастовать аргументы к нужному типу:
if (args is ConcreteArgs concreteArgs)
{
    // do something with concreteArgs
}

Это в целом не очень удобно, но просто и работает.

Правильный (на мой взгляд) вариант состоит в том, чтобы использовать шаблон программирования "посетитель", вот на хабре есть статья где рассматривается вычисление площади различных фигур - https://habr.com/ru/post/332042/.

Ещё есть вариант сделать класс generic, который принимает тип аргументов, и наложить констрейнт where T : FunctionArgs.
Ответ написан
Ваш ответ на вопрос

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

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