请告诉我一个situtation,它显示了Delegates(或)函数指针的"需要"

cla*_*aws 2 .net c c# c++

我将参加一个关于"代表和回调"的课程给那些学习级程序员的学生.他们有基本的c/c ++&c#background.而不是直接显示如何使用它们.我想展示"为什么功能指针?" 第一.我想从一个示例情况开始并问他们"你将如何做到这一点"?让他们意识到需要什么,然后将它们介绍给FunctionPointers,Delegates和CallBacks.

那么,任何人都可以向我展示一个很好的例子,它表明C/C++中C#(或)函数指针需要代理.我不想在GUI示例中使用事件处理的示例,我不希望使用类型add2numbers等示例演示"如何使用委托".

我正在寻找一些实用的例子,他们可以感受到FunctionPointers,Delegates和CallBacks的需要.

如果有任何好文章,请发布.

Jon*_*eet 7

我不确定你为什么不想使用一个GUI例子:"当我点击一个按钮时,我希望X发生 - 我现在该如何表达X?" 是一个很好的.

其他例子:

  • 我想开始一个主题:我如何表达我想要它做什么?
  • 我想过滤一些数据:如何表达过滤器?
  • 我想投影一些数据:如何表达投影?
  • 我想异步下载一个来自网络的文件:如何在下载完成后表达我想要发生的事情?

基本上每个都是说"我想以简单的方式表达一些代码".在每种情况下,您都可以使用单个方法接口 - 委托/函数指针只是一种更方便的方法.

实际上,如果一些学生习惯使用单一方法接口(例如RunnableJava),那么这可能是一个很好的起点.想象一下,如果你可以通过说"在这里使用这个方法......"来实现一个接口(并且在Java 7中看起来你将能够做到这一点;他们使用单一方法接口和方法引用代替专用委托类型.)在C#背景中,您还可以将IComparer<T>接口与Comparer<T>委托进行比较.

当然,当你有了委托的想法时,你可以引入lambda表达式(如果它是一个C#课程),向他们展示了能够表达那些逻辑"内联"的有用性.然后向他们展示如何使用lambdas作为闭包来与本地环境进行交互是有用的...


Gro*_*roo 7

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

例如,你可能有

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;
}
Run Code Online (Sandbox Code Playgroud)

要么

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;
}
Run Code Online (Sandbox Code Playgroud)

为了避免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;
}
Run Code Online (Sandbox Code Playgroud)

然后在你的代码中调用它,如下所示:

List<Person> malePersons = Filter(people, p => p.IsMale);
List<Person> femalePersons = Filter(people, p => !p.IsMale);
Run Code Online (Sandbox Code Playgroud)

请注意,现在在迭代块之外提取实际条件,您可以重复使用相同的方法来创建您喜欢的任何自定义过滤逻辑.通过提取此逻辑,您将问题委托给其他人,使您的代码松散耦合.

使用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; });
Run Code Online (Sandbox Code Playgroud)

或使用实际方法:

List<Person> malePersons = Filter(people, MaleMatch);
List<Person> femalePersons = Filter(people, FemaleMatch);
Run Code Online (Sandbox Code Playgroud)

其中谓词定义为:

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

private bool FemaleMatch(Person p)
{ 
   return !p.IsMale;
}
Run Code Online (Sandbox Code Playgroud)

重要的是要注意,我们没有传递这些方法的结果,而是传递实际的方法"指针",因此在方法内部调用方法时将返回实际结果Filter.

另请注意,.Net 3.5中的LINQ已经包含了一个Where扩展方法,该方法与此示例完全相同,还有许多其他方法使用委托条件,投影和其他内容,因此您基本上只需要传递具有相应签名的委托.


Bas*_*ard 6

我将展示如何编写/使用泛型排序函数/方法,它将回调参数作为谓词.