简体   繁体   English

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

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

I'm learning C#.我正在学习 C#。 Now I'm fiddling with delegates and events.现在我正在摆弄代表和事件。 My question is regarding the delegate: it seems I must keep the method public virtual bool IsPromotable(Employee e, PromotionDelegate pd) public.我的问题是关于委托的:似乎我必须将方法public virtual bool IsPromotable(Employee e, PromotionDelegate pd) 保持公开。 Suppose I want it protected.假设我希望它受到保护。 What do I do now?现在我该怎么做? Or is this example a bad use of the delegate?或者这个例子是对委托的错误使用? Or must I simply accept public methods when using delegates?或者我必须在使用委托时简单地接受公共方法? Below is the fully compilable code:下面是完全可编译的代码:

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

    }
}

The fact that you need to call IsPromotable on your Employee class from your class Program is the reason that it needs to be public .您需要从Program类中对Employee类调用IsPromotable的事实是它需要是public的原因。 It has nothing to do with whether or not you're using delegates.这与您是否使用委托无关。

Being public it has all of the virtues of being protected anyway. public它无论如何都具有protected所有优点。 All of the Employee class descendants can see IsPromotable and override it (as it is also virtual ).所有Employee类的后代都可以看到IsPromotable并覆盖它(因为它也是virtual )。

Now, just a couple of other hints for you.现在,给你一些其他提示。

With your OnHourlyRateChanged method in Employee you should structure the code like this:使用EmployeeOnHourlyRateChanged方法,您应该像这样构建代码:

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

The reason is that in multi-threaded code the delegate may change from after the check but before the call.原因是在多线程代码中,委托可能会在检查之后但在调用之前发生变化。 It doesn't happen often, but when it does it can cause your program to throw an exception and it becomes very hard to debug.它并不经常发生,但是当它发生时,它会导致您的程序抛出异常并且调试变得非常困难。 Your code may not be multi-threaded, but you should always get into using this pattern as a habit.您的代码可能不是多线程的,但您应该始终养成使用这种模式的习惯。

Also, in Program you have called the event handler OnHourlyRateChanged .此外,在Program您已调用事件处理程序OnHourlyRateChanged The normal convention is to use the On* naming for the method that raises the event, but not for the method that handles the event.通常的约定是对引发事件的方法使用On*命名,而不是对处理事件的方法使用On*命名。 It is more common for this method to be called something like Employee_HourlyRateChanged .这种方法被称为Employee_HourlyRateChanged东西更为常见。 Again this is a good habit to get into to avoid ambiguity in the future.同样,这是一个好习惯,可以避免将来出现歧义。

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

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