我将向学习级程序员的学生讲授“委托(delegate)和回调”类(class)。他们具有基本的c / c++和C#背景。而不是直接显示如何使用它们。我想显示“为什么要使用函数指针?”第一。我想从一个例子开始,问他们“您将如何做”?并使他们意识到需要某些东西,然后将它们介绍给FunctionPointers,Delegates和CallBacks。

因此,任何人都可以向我展示一个很好的示例,该示例说明C#(或C / C++中的函数指针)中对Delegates的需求。我不需要GUI示例中的事件处理示例,也不想使用add2numbers等示例演示“如何使用委托(delegate)”。

我正在寻找一些实际的示例,使他们可以感觉到对FunctionPointers,Delegates和CallBacks的需求。

如果有任何好的文章,请发表。

最佳答案

您可以向他们展示过滤软件中多个位置的项目列表的示例。

例如,您可能有

public List<Person> GetMale(List<Person> people)
{
   List<Person> results = new List<Person>();
   foreach (Person p in people)
   {
       if (p.IsMale)
          results.Add(p);
   }
   return results;
}

要么
public List<Person> GetFemale(List<Person> people)
{
   List<Person> results = new List<Person>();
   foreach (Person p in people)
   {
       if (!p.IsMale)
          results.Add(p);
   }
   return results;
}

为了避免在每种方法中重复foreach迭代,您将需要提取实际条件(在这种情况下为谓词),并在其他地方实现它。

因此,您将用以下两种方法替换这两种方法:
public List<Person> Filter(List<Person> people, Func<bool, Person> match)
{
   List<Person> results = new List<Person>();
   foreach (Person p in people)
   {
       if (match(p))
          results.Add(p);
   }
   return results;
}

然后像这样在您的代码中调用它:
List<Person> malePersons = Filter(people, p => p.IsMale);
List<Person> femalePersons = Filter(people, p => !p.IsMale);

注意,现在将实际条件提取到迭代块的外部,并且您可以使用相同的方法复用来创建所需的任何自定义过滤逻辑。通过提取此逻辑,您可以将问题委派给其他人,从而使您的代码松耦合。

使用C#2.0匿名方法语法,调用此方法将如下所示:
List<Person> malePersons = Filter(people,
   delegate (Person p) { return p.IsMale; });
List<Person> femalePersons = Filter(people,
   delegate (Person p) { return !p.IsMale; });

或使用实际方法:
List<Person> malePersons = Filter(people, MaleMatch);
List<Person> femalePersons = Filter(people, FemaleMatch);

谓词定义为:
private bool MaleMatch(Person p)
{
   return p.IsMale;
}

private bool FemaleMatch(Person p)
{
   return !p.IsMale;
}

重要的是要注意,我们不是传递这些方法的结果,而是传递实际的方法“指针”,因此当在Filter方法内部调用该方法时,将返回实际结果。

还要注意LINQ in .Net 3.5已经包含一个Where扩展方法,该方法执行与本示例相同的操作,以及许多其他使用委托(delegate)进行条件,投影和其他操作的方法,因此您基本上只需要传递具有适当签名的委托(delegate)即可。

08-19 23:20