多播委托:在其他方法中向委托添加方法引用时的不同行为

时间:2013-07-29 20:58:56

标签: c# .net

我在下面的代码中声明了一个委托:

delegate void EmployeeSalaryCalculated(int idEmp);

我有这些简单的课程:

    class Employee
    {
        public void CalculateSalary(int idEmp){}
    }

    class Payroll
    {
        public void EmpSalNotification(int idEmp) { }            

        public void SetMethod(ref EmployeeSalaryCalculated esc)
        {
            esc += this.EmpSalNotification;
        }         
    }

    class HR
    {
        public void EmpSalNotification(int idEmp) { }           

        public void SetMethod(ref EmployeeSalaryCalculated esc)
        {
            esc = this.EmpSalNotification;
        }
    }

以下按钮处理程序使用上述类:

private void btnStart_Click(object sender, EventArgs e)
        {              
            Payroll payroll = new Payroll();
            HR hr = new HR();            

            EmployeeSalaryCalculated empSalCalculated = null;
            empSalCalculated += payroll.EmpSalNotification;
            empSalCalculated += hr.EmpSalNotification;

            // This invokes both methods - fine. 
            // empSalCalculated.GetInvocationList() returns 2
            empSalCalculated.Invoke(108);

            EmployeeSalaryCalculated empSalCalculated2 = null;
            payroll.SetMethod(ref empSalCalculated2);
            hr.SetMethod(ref empSalCalculated2);

            // This however, invokes only one method!
            // empSalCalculated2.GetInvocationList() returns 1
            empSalCalculated2.Invoke(108);    
        }

尽管通过ref传递了委托对象empSalCalculated2,但它只执行一个函数,而不像执行这两个函数的委托对象empSalCalculated

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

问题在于HR.SetMethod类的这一行:

esc = this.EmpSalNotification;

此行会覆盖以前的esc值。因此,考虑到您从对象调用SetMethod的顺序,empSalCalculated2仅包含来自HR实例的方法,该方法已执行。

要解决此问题,您可能需要重写HR.SetMethod

esc += this.EmpSalNotification;

或颠倒调用SetMethod的顺序:

hr.SetMethod(ref empSalCalculated2);
payroll.SetMethod(ref empSalCalculated2);

答案 1 :(得分:1)

我认为这是你人力资源班的一个错字

class HR
    {
        public void EmpSalNotification(int idEmp) { }           

        public void SetMethod(ref EmployeeSalaryCalculated esc)
        {
            // this is =, not +=, so only one ref is held at a time
            esc = this.EmpSalNotification; 
        }
    }

答案 2 :(得分:1)

您的代码中只是一个错字:

esc += this.EmpSalNotification;  

vs

 esc = this.EmpSalNotification;