订阅作为方法参数

时间:2015-11-05 21:23:39

标签: c# delegates ref

我正在尝试将重复编程模式构建到泛型类中以便重用代码。部分此模式在异步操作期间根据需要线程安全地订阅/取消订阅委托(多播委托用作事件)。

以下代码无法编译。我面临的问题是C#允许我传递一个委托作为方法参数,但是在MyWorker类中的任何地方,subscribe + =, - = operations会导致错误。 (从外面对同一个代表工作正常)。

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

语法错误? 委托范围限制? 这种语言不允许这种情况吗?

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());
    }
}

请注意,仿制药似乎不是原因;我尝试使用静态类型而不是相同的结果。我也尝试使用'ref'关键字传递委托,以确保我存储和引用原始对象而不是本地副本......可能是次要问题,但一次只能一步。

[UPDATE]

OIC,无法约束委托类型似乎是一个主要问题,并且以我的方式阻止通用。谢谢你指出罗恩。

澄清原意:
我使用代表进行内部活动;比严格的'事件'类型更灵活。我正在寻找一些方法在运行时将委托(ref?)传递给MyWorker类。然后MyWorker执行一些后台任务,在最终退出垃圾收集之前,根据需要订阅和取消订阅以在操作期间接收事件。我为30多个几乎相同的任务/事件执行此操作,这就是为什么创建可重用(通用?)类是非常需要的。

我系统中的代表有严格的表格,例如:

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

计划B是将Action委托传递给MyWorker中的订阅和取消订阅。这有点麻烦,因为它需要2个动作&lt;&gt;为每次调用创建,而不是仅仅干净地传递所需的委托。

对任何建议开放......

1 个答案:

答案 0 :(得分:0)

这不是因为您将通用参数命名为delegateT编译器知道它是某种委托类型,因此它无法知道该类型上存在某些+ =运算符。 需要一些通用约束来强制执行此操作;但AFAIK在C#中是不可能的

正如KiwiPiet在评论中指出的那样,您可以尝试为某些委托类型添加约束,但
正如Ron Beyer在评论中指出的那样,它也不可能限制某些委托类型