Thread overview
How to declare "abstract" delegates list?
May 05, 2017
RedCAT
May 06, 2017
bauss
May 06, 2017
bauss
May 07, 2017
RedCAT
May 05, 2017
Hello!

Is it possible to create a list of slightly different delegates?

For example, there is a class hierarchy:

class Base;
class DerivedOne : Base;
class DerivedTwo : Base;

And there are several delegates:

void delegate(int, Base);
void delegate(int, DerivedOne);
void delegate(int, DerivedTwo);

It's easy to see that the only difference in the declarations of these delegates is the type of the second parameter, this is the class inherited from Base.

How can I create a list or an array where I can add these delegates?
May 06, 2017
On Friday, 5 May 2017 at 14:20:43 UTC, RedCAT wrote:
> Hello!
>
> Is it possible to create a list of slightly different delegates?
>
> For example, there is a class hierarchy:
>
> class Base;
> class DerivedOne : Base;
> class DerivedTwo : Base;
>
> And there are several delegates:
>
> void delegate(int, Base);
> void delegate(int, DerivedOne);
> void delegate(int, DerivedTwo);
>
> It's easy to see that the only difference in the declarations of these delegates is the type of the second parameter, this is the class inherited from Base.
>
> How can I create a list or an array where I can add these delegates?

I would do something like this:

interface IMyDelegate { }

final class MyDelegate(T) : IMyDelegate {
    private:
    void delegate(int, T) _d;

    public:
    this(void delegate(int, T) d) {
        _d = d;
    }

    void opCall(int x, T y) {
        _d(x, y);
    }
}

... Below is simple usage demonstration ...

private IMyDelegate[] _delegates;

void addDelegate(T)(void delegate(int, T) d) {
    _delegates ~= new MyDelegate!T(d);
}

auto getDelegate(size_t index) {
    return cast(MyDelegate!T)_delegates[index];
}

...

void func1(int, Base) { ... }
void func2(int, DerivedOne) { ... }
void func3(int, DerivedTwo) { ... }

...

addDelegate(&func1);
addDelegate(&func2);
addDelegate(&func3);

(getDelegate!Base)(100, base);
(getDelegate!DerivedOne)(100, derivedOne);
(getDelegate!DerivedTwo)(100, derivedTwo);

By theory that should work. It's untested, so you might need a few tweaks here and there.
May 06, 2017
On Saturday, 6 May 2017 at 06:07:01 UTC, bauss wrote:
> On Friday, 5 May 2017 at 14:20:43 UTC, RedCAT wrote:
>> [...]
>
> I would do something like this:
>
> [...]

You could also do use alias this to use the delegate instead of the class encapsulating the delegate.
May 07, 2017
On Saturday, 6 May 2017 at 06:07:01 UTC, bauss wrote:
> By theory that should work. It's untested, so you might need a few tweaks here and there.

Thanks!