【问题标题】:c# Why delegate\event doesn't get updated after passing it to another classc#为什么delegate\event在传递给另一个类后没有得到更新
【发布时间】:2017-01-16 13:57:01
【问题描述】:

我在调用将事件传递给特定类后添加的委托时遇到问题,我认为委托将更新作为对象..

例如,我将委托传递给的类:

更新代码(由于 cmets 中的一些问题)

这实际上是 +- 我需要如何运行它,“ExecutorOnCalculationCompleted”从不调用(请忽略睡眠和同步,我将代码缩小到所需部分)

    class Executor
{

    public delegate void CalculationCompletEventHandler(int score);

    public event CalculationCompletEventHandler CalculationCompleted;

    public void Start()
    {
        CalculationCompleted += OnCalculationCompleted;
        Plus plus = new Plus(1, 2, CalculationCompleted);
        Minus minus =  new Minus(5, 2, CalculationCompleted);
        Multi multi =  new Multi(5, 2, CalculationCompleted);
        ...
        ...    They will work async...
    }

    private void OnCalculationCompleted(int score)
    {
        Console.WriteLine("OnCalculationCompleted , score=" + score);
    }
}

class Plus
{
    private Executor.CalculationCompletEventHandler _calculationCompletEventHandler;
    private int a;
    private int b;

    public Plus(int a, int b,Executor.CalculationCompletEventHandler calculationCompletEventHandler)
    {
        this.a = a;
        this.b = b;
        _calculationCompletEventHandler = calculationCompletEventHandler;
    }

    public void Calculate()
    {
        _calculationCompletEventHandler?.Invoke(a+b);
    }
}



class Program
{

    static void Main(string[] args)
    {
        Executor executor = new Executor();
        executor.Start(); // async action
        executor.CalculationCompleted += ExecutorOnCalculationCompleted;
        ...
    }

    // This method doesn't get invoked when the class inside Executor fire the event.
    private static void ExecutorOnCalculationCompleted(int score)
    {
        Console.WriteLine("ExecutorOnCalculationCompleted , score=" + score);
    }
}

【问题讨论】:

  • 那是因为代表的引用不一样。 += 使用 Delegate.Combine 创建一个新委托
  • 实际上事件必须在Plus方法内,你为Subtract等编写相同的事件,委托必须在全局命名空间中,不要放在类中。 Executor 将其方法订阅到 Plus 和 Subtract 等各个事件
  • 你到底想在这里做什么?你的目标是什么?为此,Plus 需要拥有该事件,但是添加一个 Multiply 类会发生什么?
  • 嗨@M.kazemAkhgary,我更新了我的代码希望这能澄清一些问题
  • 请将其缩减为minimal reproducible example。目前还不足以实际运行代码,但您确实拥有比您需要的更多。

标签: c# events reference delegates invoke


【解决方案1】:

您在构造函数中直接传递委托。我想你想把这个事件放到课堂上。示例:

class Plus
{
    public delegate void CalculationCompletEventHandler(int score);
    public event CalculationCompletEventHandler CalculationCompleted;

    private int a;
    private int b;

    public Plus(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    public void Calculate()
    {
        if (CalculationCompleted != null)
        {
            CalculationCompleted(a + b);
        }
    }
}

你现在可以这样使用它了:

void Main()
{
    Plus plus = new Plus(1, 2);
    plus.CalculationCompleted += OnCalculationCompleted;
    plus.Calculate();

    plus.CalculationCompleted += OnCalculationCompleted2;
    plus.Calculate();        
}

private void OnCalculationCompleted(int score)
{
    Console.WriteLine("OnCalculationCompleted , score=" + score);
}

private void OnCalculationCompleted2(int score)
{
    Console.WriteLine("OnCalculationCompleted2 , score=" + score);
}

正如评论中提到的,如果在程序的不同部分使用委托类型,您可能只需要事件本身。

问题更新后

如果您希望在执行程序中执行该事件,我只需将一个操作传递给您的每个类,例如 PlusMultiply... 并从执行程序调用该事件:

class Executor
{
    public delegate void CalculationCompletEventHandler(int score);
    public event CalculationCompletEventHandler CalculationCompleted;

    public void Start()
    {
        CalculationCompleted += OnCalculationCompleted;
        Plus plus = new Plus(1, 2, FireEvent);        
    }

    private void FireEvent(int score)
    {
        if (CalculationCompleted != null)
        {
            CalculationCompleted(score);
        }
    }

    private void OnCalculationCompleted(int score)
    {
        Console.WriteLine("OnCalculationCompleted , score=" + score);
    }
}

class Plus
{
    private int a;
    private int b;
    private Action<int> completionAction

    public Plus(int a, int b, Action<int> completionAction)
    {
        this.a = a;
        this.b = b;
        this.completionAction = completionAction;       
    }

    public void Calculate()
    {
        this.completionAction(a + b);
    }
}

【讨论】:

  • 没错,但由于这个委托 (CalculationCompletEventHandler) 似乎在多个类之间共享(正如它的名字所暗示的那样)它不应该在 Plus 内,所以它可以用于说 @ 987654328@等
  • @M.kazemAkhgary 好的,那么只有事件应该在 Plus 类中
  • 嗨@Nico,我更新了我的代码希望这能澄清一些问题
  • 是的!这样就行了!从父类调用事件。谢谢!
猜你喜欢
  • 2018-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-17
  • 2016-07-26
  • 1970-01-01
  • 1970-01-01
  • 2016-07-20
相关资源
最近更新 更多