简体   繁体   English

订阅作为方法参数传递的委托

[英]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. 我面临的问题是C#允许我将委托作为方法参数传递,但是在MyWorker类内部的任何地方,subscribe + =,-=操作都会导致错误。 (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. 我还尝试通过传递带有'ref'关键字的委托来确保我正在存储和引用原始对象,而不是本地副本...可能是次要问题,但每次仅一步。

[UPDATE] [更新]

OIC, inability to constrain Delegate type seems to be a major issue here, and prevents generic usage the way I'm doing it. OIC,无法约束委托类型似乎是这里的主要问题,并妨碍了我使用通用方法。 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. 我正在寻找某种在运行时将委托(ref?)传递给MyWorker类的方法。 Then MyWorker performs some background tasks which subscribe and unsubscribe as necessary to receive events during operation, before finally exiting for garbage collection. 然后,MyWorker执行一些后台任务,这些任务将根据需要订阅和取消订阅,以在操作期间接收事件,然后最终退出进行垃圾回收。 I do this for 30+ nearly identical tasks/events, which is why creating a reusable (generic?) class is highly desirable. 我为30多个几乎相同的任务/事件执行此操作,这就是为什么非常需要创建可重用(泛型?)类的原因。

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. 计划B将通过Action委托从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. 这有点麻烦,因为它需要为每个调用创建2个Actions <>,而不仅仅是干净地传递所需的委托。

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. 这不是因为您为通用参数delegateT命名的,编译器知道它是某种委托类型,所以它不知道该类型上存在+ =运算符。 It would need some generic constraint to enforce this ; 实施此操作需要一些通用约束; but AFAIK that's not possible in C# 但是AFAIK在C#中是不可能的

As KiwiPiet pointed in comment you can maybe try to add a constraint for some delegate type though 正如KiwiPiet在评论中指出的那样,您可以尝试为某些委托类型添加约束
As pointed by Ron Beyer in comment it's also not possible to constraint to some delegate type too 正如罗恩·拜尔(Ron Beyer)在评论中指出的那样,也不可能限制某些委托人类型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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