我将参加一个关于"代表和回调"的课程给那些学习级程序员的学生.他们有基本的c/c ++&c#background.而不是直接显示如何使用它们.我想展示"为什么功能指针?" 第一.我想从一个示例情况开始并问他们"你将如何做到这一点"?让他们意识到需要什么,然后将它们介绍给FunctionPointers,Delegates和CallBacks.
那么,任何人都可以向我展示一个很好的例子,它表明C/C++中C#(或)函数指针需要代理.我不想在GUI示例中使用事件处理的示例,我不希望使用类型add2numbers等示例演示"如何使用委托".
我正在寻找一些实用的例子,他们可以感受到FunctionPointers,Delegates和CallBacks的需要.
如果有任何好文章,请发布.
我不确定你为什么不想使用一个GUI例子:"当我点击一个按钮时,我希望X发生 - 我现在该如何表达X?" 是一个很好的.
其他例子:
基本上每个都是说"我想以简单的方式表达一些代码".在每种情况下,您都可以使用单个方法接口 - 委托/函数指针只是一种更方便的方法.
实际上,如果一些学生习惯使用单一方法接口(例如RunnableJava),那么这可能是一个很好的起点.想象一下,如果你可以通过说"在这里使用这个方法......"来实现一个接口(并且在Java 7中看起来你将能够做到这一点;他们使用单一方法接口和方法引用代替专用委托类型.)在C#背景中,您还可以将IComparer<T>接口与Comparer<T>委托进行比较.
当然,当你有了委托的想法时,你可以引入lambda表达式(如果它是一个C#课程),向他们展示了能够表达那些逻辑"内联"的有用性.然后向他们展示如何使用lambdas作为闭包来与本地环境进行交互是有用的...
您可以向他们展示过滤软件中多个位置的项目列表的示例.
例如,你可能有
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扩展方法,该方法与此示例完全相同,还有许多其他方法使用委托条件,投影和其他内容,因此您基本上只需要传递具有相应签名的委托.