c# - 将方法作为参数传递 vs 直接调用方法

标签 c# .net delegates

我在一些例子中看到过作为参数传递的方法。如果我可以从另一个方法调用一个方法,我为什么要将方法作为参数传递?这种设计背后的目的是什么?

  1. 从一个方法调用另一个方法
  2. 使用委托(delegate)或Action 将方法作为参数传递

最佳答案

将方法作为参数传入可用于防止依赖和耦合。让我们看一下如何将其用于策略模式:

假设我们有一个方法 PrintReport,它打印给定的项目列表,这些项目可能根据参数按名称或类型排序。这是天真的方法:

public void PrintReport (List<Item> data, SortOrder sortBy)
{
    List<Item> sortedItems;
    switch (sortBy)
    {
        case SortOrder.Name: sortedItems = SortByName(data); break;
        case SortOrder.Type: sortedItems = SortByType(data); break;
    }

    Print(sortedItems);
}

它很简单但很有效。但是当我们想要添加一个新的排序顺序时会发生什么?我们需要更新 SortOrder 枚举,进入 PrintReport 并添加一个新的 case 并调用新的 SortByWhatever 方法。

但是如果我们传入一个方法作为参数,我们的 PrintReport 可以更简单并且不关心排序实现:

public void PrintReport (List<Item> data, Func<List<Item>, List<Item>> sorter)
{
    List<Item> sortedItems = sorter(data);
    Print(sortedItems);
}

现在无论如何都可以定义排序函数,甚至可以在 PrintReport 甚至不知道的不同程序集中定义。它可以是 lambda 函数或临时定义的匿名方法。但在所有情况下,我们的方法都会接收委托(delegate),使用它进行排序,然后打印报告。

这是一个用法示例。起初看起来我们只是将 switch/case 移到了函数之外,这很重要,因为它允许不同的调用者有不同的逻辑。但请注意第三种情况。

public void HandleData()
{
    switch (ReportItemOrder)
    {
        case SortOrder.Name: PrintReport(data, SortByName); break;
        case SortOrder.Type: PrintReport(data, SortByType); break;
        case SortOrder.Whatever: 
        Func<List<Item>, List<Item>> customSort = (items) => /* do something */;
        PrintReport(data, customSort);
    }
}

关于c# - 将方法作为参数传递 vs 直接调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15585358/

相关文章:

c# - 通过 jQuery 从发布请求的部分 View 中检索数据

c# - 通过 Gmail 在 .NET 中发送电子邮件

c# - 扩展方法不更新传入的对象

.net - 如何序列化指向被覆盖的虚拟方法基础的委托(delegate)?

c# - 在 C# 中非对称验证 JWT

c# - SelectedValues 在 MultiSelectList mvc 中不起作用

c# - 通用类型转换

c# - 如何使用NEST删除特定的河流?

c# - 这个委托(delegate)用法的目的是什么?

iphone - 两个 View Controller 可以成为彼此的委托(delegate)吗?