c# - 更好地理解委托(delegate),一些解释

标签 c# delegates

我知道您何时使用委托(delegate)、它们如何工作,以及您可以使用 ActionFunc 等内置类型来使用委托(delegate)。

但我想真正的含义我还是不明白。因为我有这个样本:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    // A method that processes an employee.
    // private delegate void EmployeeProcessor(Employee employee);

    // The employees.
    //  Employee employee;
    private List<Employee> Employees = new List<Employee>();

    private void Form1_Load(object sender, EventArgs e)
    {
        // Make some employees.
        MakeEmployees();

        // Show the employees.
        ShowEmployees();
    }

    // Add a single employee to the form's ListBox.
    private void ListEmployee(Employee employee)
    {
        employeesListBox.Items.Add(
            employee.Name + ", " +
            employee.Title + ", " +
            employee.Salary.ToString("C"));
    }

    // Do something for all employees.
    private void ProcessEmployees(Action<Employee> process)
    {
        foreach (Employee employee in Employees)
            process(employee);
    }

    // Display all employees in the form's ListBox.
    private void ShowEmployees()
    {
        employeesListBox.Items.Clear();
        ProcessEmployees(ListEmployee);
    }

    // Make some employees.
    private void MakeEmployees()
    {
        Employees.Add(new Employee()
        {
            Name = "Alice Archer",
            Title = "Programmer",
            Salary = 60000m,
        });
        Employees.Add(new Employee()
        {
            Name = "Bob Baker",
            Title = "Engineer",
            Salary = 70000m,
        });
        Employees.Add(new Employee()
        {
            Name = "Cindy Carter",
            Title = "Manager",
            Salary = 80000m,
        });
    }

    // Give a single employee a raise.
    private void GiveRaise(Employee employee)
    {
        employee.Salary *= 1.1m;
    }

    private void GiveRaise2()
    {
        foreach (var employee2 in Employees)
        {
            employee2.Salary *= 1.1m;
        }
    }

    // Give all employees a raise.
    private void giveRaisesButton_Click(object sender, EventArgs e)
    {
        GiveRaise2();// Without Delegate
        ProcessEmployees(GiveRaise); //With delegate
        ShowEmployees();
    }
}

所以我举了两个例子。 ONe 正在使用委托(delegate)。而且一个人没有使用委托(delegate)。然后您必须迭代员工列表。

当然还有这个:

ProcessEmployees(GiveRaise); //With delegate

你有一个方法并将一个方法作为参数传递给它。所以看来你做了一些封装。但这是委托(delegate)的真正好处吗?你封装了函数。

当然,您不必再次迭代员工列表。因为这当然更短:

private void GiveRaise(Employee employee)
{
    employee.Salary *= 1.1m;
}

希望得到一些我误解的反馈。

对我来说,这似乎也像特定对象的过滤器一样工作。因为在本例中你有一个对象 Employee。您想与该员工一起做一些事情。所以加薪或者把他们组合在一起。

那么最后你就不必重复代码了?这也正确吗?

最佳答案

在您的示例中,使用委托(delegate)没有太大意义,因为所有内容都在类中(此处为 Form1)。如果委托(delegate)及其使用者位于不同的类中,尤其是与泛型结合使用,它们就更有意义。

假设您有这个简单的类:

public class Calculator<T>
{
   public decimal Average(List<T> items, Func<T, decimal> getValue)
   {
        decimal sum = 0;

        foreach (var item in items)
            sum += getValue(item);

        return sum / items.Count();
   }
}

在您的 Form1 中,您可以创建一个方法

private decimal GetSalary(Employee employee)
{
    return employee.Salary;
}

并像这样使用

var calc = new Calculator<Employee>();
var avg = calc.Average(Employees, GetSalary);

或者您可以通过不使用 GetSalary 方法并使用 lambda 表达式来简化此操作:

var avg = calc.Average(Employees, e => e.Salary);

但现在真正的好处是,您也可以轻松地在其他类中重用计算器,假设您有此类:

public class Product
{
    public decimal Weight { get; set; }
}

然后你就可以这样做

var calc = new Calculator<Product>();
var avgWeight = calc.Average(listOfProducts, p => p.Weight);

关于c# - 更好地理解委托(delegate),一些解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58361810/

相关文章:

c# - 通过 Feeder 进行 WIA 扫描

iphone - 一个对象可以作为多个委托(delegate)人的委托(delegate)吗?

iOS 在自定义类中处理 didSelectRowAtIndexPath

xcode - 使用调试器断点在 Xcode 8.1/Swift 3.0 中调用两次委托(delegate)方法

swift - 从委托(delegate)方法修改 View Controller 属性

c# - 在 C# 中执行下一个方法之前等待一个方法完成

c# - 如何反序列化对对象列表的 JSON 响应

C# 如何将虚拟键码转换为字符?

c# - 如何在运行时获取静态类的方法名?

c# - 在进行跨应用程序域开发时,如何以与代理相同的方式赋予委托(delegate)无限生命?