csrss Ответов: 1

Динамическая множественная отправка


Привет всем! :)
Речь идет о динамической диспетчеризации объекта. Вот код, который приведет к сбою:
interface IDispatcher
    {
        void Dispatch(dynamic obj);
    }

    class MyClass1
    {
    }
    class MyClass2
    {
    }

    class Dispatcher1 : IDispatcher
    {
        public void Dispatch(dynamic obj)
        {
            Console.WriteLine("Dispatcher.Dispatch dynamic");
            Dispatch(obj);
        }
        public void Dispatch(MyClass1 cl)
        {
            Console.WriteLine("Dispatcher.Dispatch MyClass1");
        }
    }

    class Dispatcher2 : IDispatcher
    {
        public void Dispatch(dynamic obj)
        {
            Console.WriteLine("Dispatcher.Dispatch dynamic");
            Dispatch(obj);
        }
        public void Dispatch(MyClass2 cl)
        {
            Console.WriteLine("Dispatcher.Dispatch MyClass2");
        }
    }

    class Dispatchers
    {
        public void Add(IDispatcher disp)
        {
            _list.Add(disp);
        }
        public void DispatchAll(object data)
        {
            _list.ForEach(x => x.Dispatch(data));
        }
        readonly List<IDispatcher> _list = new List<IDispatcher>();
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Dispatchers disps = new Dispatchers();
                disps.Add(new Dispatcher1());
                disps.Add(new Dispatcher2());

                MyClass2 cl = new MyClass2();
                disps.DispatchAll(cl);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadKey();
        }
    }


Что я уже пробовал:

Итак, как вы можете видеть из вышесказанного, я добавляю диспетчеров в коллекцию, которая должна обрабатывать какой-то объект. Вся идея, конечно, заключается в том, чтобы иметь возможность добавлять новых диспетчеров, а также конкретный диспетчер не будет знать о каждом объекте - поэтому каждый диспетчер знает, скажем, об одном типе объекта. Пока поступают новые объекты, они передаются в коллекцию диспетчеров, и эта коллекция не должна рушиться, если она не знает новых объектов.
В настоящее время этот код, конечно, завершится сбоем, потому что первый диспетчер не знает о предоставленном объекте (который будет отправлен во втором диспетчере), и поэтому он будет вызывать Dispatch(динамический объект) в цикле до тех пор, пока он не завершится сбоем с StackOverflowException.

Итак, вопрос в том, что я должен сделать, чтобы "остановить" цикл диспетчеризации в диспетчере, который не имеет обработчика для конкретного типа объекта?
Спасибо

Кстати, я знаю, что могу добавить некоторые флаги и целые числа для инкремента и проверить, сколько раз вызывался метод Dispatch или наследовать MyClass от базового класса и предоставить метод Dispatch(BaseClass), который остановится здесь.
Но я ищу "цивилизованное" решение, например, этот код будет частью API, который будет предоставлен разработчикам для дальнейшей разработки кода.

1 Ответов

Рейтинг:
9

#realJSOP

Вот один из способов - просто вызвать метод Process в каждом диспетчере.

public class Dispatcher1
{
    public Dispatcher1()
    {
    }

    public bool Process(object data)
    {
        if (data is Object1)
        {
            ProcessThisObject((Object1)data);
            return true;
        }
        return false;
    }
}