簡體   English   中英

C# 委托后果:不喜歡公共方法

[英]C# delegate consequence: don't like the public method

我正在學習 C#。 現在我正在擺弄代表和事件。 我的問題是關於委托的:似乎我必須將方法public virtual bool IsPromotable(Employee e, PromotionDelegate pd) 保持公開。 假設我希望它受到保護。 現在我該怎么做? 或者這個例子是對委托的錯誤使用? 或者我必須在使用委托時簡單地接受公共方法? 下面是完全可編譯的代碼:

using System;

namespace Delegate_Tutorial_1
{

    public class EmployeeEventArgs : EventArgs
    {
        public Employee Employee { get; set; }
    }

    //--

    public class Employee
    {
        public string Name { get; set; }
        public int YearsOfService { get; set; }

        public event EventHandler<EmployeeEventArgs> HourlyRateChanged;

        private double hourlyRate;
        public double HourlyRate
        {
            get { return hourlyRate; }
            set
            {
                if (hourlyRate != value)
                {
                    hourlyRate = value;
                    OnHourlyRateChanged();
                }
            }
        }

        protected virtual void OnHourlyRateChanged()
        {
            if (HourlyRateChanged != null)
                HourlyRateChanged(this, new EmployeeEventArgs() { Employee = this});
        }


        public virtual bool IsPromotable(Employee e, PromotionDelegate pd)
        {
            return pd(e);
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Delegate_Tutorial_1
{
    public delegate bool PromotionDelegate(Employee emp);

    class Program
    {
        static void Main(string[] args)
        {

            PromotionDelegate promoDelegate = PromotionCheck;

            List<Employee> EmployeeList = new List<Employee>();
            EmployeeList.Add(new Employee() { Name = "John", YearsOfService = 5, HourlyRate = 15 });
            EmployeeList.Add(new Employee() { Name = "Mary", YearsOfService = 4, HourlyRate = 17 });

            foreach (Employee emp in EmployeeList)
            {
                emp.HourlyRateChanged += OnHourlyRateChanged; //Subscribe to the event of the Employee

                if (emp.IsPromotable(emp, promoDelegate))
                {
                    emp.HourlyRate *= 1.1;
                    Console.WriteLine(emp.Name + " : eligable for promotion. Salary now is: " + emp.HourlyRate);
                }
            }
            Console.ReadLine();
        }


        //--

        public static bool PromotionCheck(Employee emp)
        {
            return emp.YearsOfService >= 5 ? true : false;
        }

        public static void OnHourlyRateChanged(object source, EmployeeEventArgs args)
        {
            Console.WriteLine("Hourly salary has been changed for: " + args.Employee.Name);
        }

    }
}

您需要從Program類中對Employee類調用IsPromotable的事實是它需要是public的原因。 這與您是否使用委托無關。

public它無論如何都具有protected所有優點。 所有Employee類的后代都可以看到IsPromotable並覆蓋它(因為它也是virtual )。

現在,給你一些其他提示。

使用EmployeeOnHourlyRateChanged方法,您應該像這樣構建代碼:

protected virtual void OnHourlyRateChanged()
{
    var hrc = this.HourlyRateChanged;
    if (hrc != null)
    {
        hrc(this, new EmployeeEventArgs() { Employee = this });
    }
}

原因是在多線程代碼中,委托可能會在檢查之后但在調用之前發生變化。 它並不經常發生,但是當它發生時,它會導致您的程序拋出異常並且調試變得非常困難。 您的代碼可能不是多線程的,但您應該始終養成使用這種模式的習慣。

此外,在Program您已調用事件處理程序OnHourlyRateChanged 通常的約定是對引發事件的方法使用On*命名,而不是對處理事件的方法使用On*命名。 這種方法被稱為Employee_HourlyRateChanged東西更為常見。 同樣,這是一個好習慣,可以避免將來出現歧義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM