简体   繁体   中英

Subscribe to a delegate that was passed as method argument

I'm attempting to build a recurring programming pattern into a generic class for code re-use. Part of this pattern thread-safely subscribes/unsubscribes to a delegate as needed during asynchronous operations (multicast delegate used as event).

The following code does not compile. The problem I'm facing is that C# allows me to pass a delegate as method argument, but anywhere inside MyWorker class the subscribe +=,-= operations cause errors. (Works fine on the same delegate from outside).

[Operator '+=' cannot be applied to operands of type 'delegateT' and 'method group']

Syntactical errors? delegate scope limitation? is this disallowed by the language?

public class MyWorker<delegateT,argT>
{
    private delegateT mDelegate;

    public MyWorker(delegateT d)
    {
        mDelegate = d; //save delegate (reference?) for use later
    }

    public void DoWorkAsync()
    {
        mDelegate += m_subscriber; //ERROR: Operator '+=' cannot be applied to operands of type 'delegateT'...

        //...Do some work that causes delegate to fire...

        mDelegate -= m_subscriber; //ERROR: Operator '-=' cannot be applied to operands of type 'delegateT'...
    }

    private void m_subscriber(argT arg)
    {
        Console.WriteLine("Received: " + arg.ToString());
    }
}

Note that generics do not seem to be the cause; I've tried using static types instead with the same result. I've also tried passing delegate with the 'ref' keyword to make sure i'm storing and referencing the original object rather than a local copy...maybe a secondary issue, but one step at a time.

[UPDATE]

OIC, inability to constrain Delegate type seems to be a major issue here, and prevents generic usage the way I'm doing it. Thanks for pointing that out Ron.

To clarify the original intent:
I use delegates for internal events; more flexibility than strict 'event' type. I'm searching for some way to pass a delegate (ref?) to MyWorker class at runtime. Then MyWorker performs some background tasks which subscribe and unsubscribe as necessary to receive events during operation, before finally exiting for garbage collection. I do this for 30+ nearly identical tasks/events, which is why creating a reusable (generic?) class is highly desirable.

Delegates in my system have a strict form such as:

delegate void delegateEvent1(Class1 arg);
delegate void delegateEvent2(Class2 arg);
...
delegate void delegateEventN(ClassN arg);

Plan B is to pass Action delegates to subscribe and unsubscribe from within MyWorker. This is quite a bit messier as it requires 2 Actions<> to be created for each invocation rather than just cleanly passing the desired delegate.

Open to any suggestions...

It's not because you named your generic parameter delegateT compiler knows it's some delegate type and so it can't know that some += operator exists on that type. It would need some generic constraint to enforce this ; but AFAIK that's not possible in C#

As KiwiPiet pointed in comment you can maybe try to add a constraint for some delegate type though
As pointed by Ron Beyer in comment it's also not possible to constraint to some delegate type too

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM