当前位置: 首页 > 编程语言 > C#

C#DelegatesRealWorld用法分享

时间:2023-04-10 16:07:42 C#

C#DelegatesRealWorldUsage之前问过一个关于delegates的问题,有没有必须要用delegates的情况?这如何改进我的C#代码?就像我使用它的许多场景一样,我似乎总是能够围绕它进行编程。假设你不是在谈论事件——当然你可以围绕它进行编程。关键是让它变得更好更干净。protectedvoidSort(){foreach(_dBase.Keys中的字符串键){Array.Sort>>(_dBase[key],newComparison>>(delegate(Pair>a,Pair>b){if(a==null&&b!=null)返回1;elseif(a!=null&&b==null)返回-1;elseif(a==null&&b==null)返回0;elsereturna.First.CompareTo(b。第一的);}));我可以在没有内联代表的情况下这样做吗?当然。我的类中是否有仅用于此实例的软盘私有方法?正确的。编辑:如评论中所述,您可以简化:Array.Sort>>(_dBase[key],newComparison>>(delegate(Pair>a,Pair>b){toArray.Sort>>(_dBase[key],(a,b)=>{每当你使用Strategy模式或Observer模式时,委托都会使你的工作比使用接口更容易。如果你想象没有委托的C#,你通常会遇到使用方法拥有类或接口的情况.方法的名称是多余的。例如publicinterfaceIGetMail{MailJustGetTheMail();}接口就是那个方法。对该类型对象的引用实际上只不过是对单个可调用方法的引用。调用代码:Mailm=getMail.JustGetTheMail();可以简化为:Mailm=getMail();编译器可以毫无歧义地将其视为“语法糖”,因为只有一种方法可以调用getMail引用。因此,让我们将此功能添加到我们的C#编译器中。现在我们还可以在声明这些类型时使其更清晰。我们在调用的时候不需要指定方法名,那为什么要先给方法起个名字呢?让我们选择一个标准方法名称Invoke,它是publicinterfaceIGetMail{MailInvoke();我们将添加更多的语法糖,这样我们就可以把它写成:publicdelegateMailGetMail();嘿,转眼间。我们已将代理添加到我们的C#编译器。(从技术上讲,CLR也知道代理,因此C#编译器不会生成接口,而是生成一个特殊的“委托”类型,它支持异步调用,并操作一个不可变的委托列表,并将它们视为单个引用,但在基本形成它可以用接口来完成。有人建议为Java做这个。然后我们可以更进一步并添加匿名委托-使它们简洁,以接口不是的方式实现。所以回答你的问题-任何时候你的接口有一个方法,它可能是一个委托,你将能够大大减少你必须编写的垃圾代码的数量。没有人提到这一点,但如果你使用LINQ和Lambda,你总是使用匿名方法......从技术上讲,它仍然代表.假设你有一个名为Person的类classPerson{publicstringFirstName{get;放;}publicstringLastName{get;放;}}你想实现一个查找方法,你可以根据名字找到这个人publicPersonWhere(Listlist,stringfirstName){//findthestringforeach(Personiteminlist)if(item.FirstName.Equals(firstName))返回项目;这是一个非常具体的搜索,不是很动态,这意味着如果你想按姓氏搜索你必须改变这个方法或写一个新的。幸运的是,LINQ提供了一个名为Where的扩展方法,你需要传递一个委托,你可以借助匿名方法动态创建委托。例如stringsearchString="Stan";list.Where(person=>person.FirstName.Equals(searchString));但是如果你想更改为按姓氏搜索,你可以只执行此字符串searchString="R";list.Where(person=>person.LastName.Equals(searchString));这个例子可能不是你想要的,但我只是想表明有时我们一直在使用代理而不考虑或实施它。真实世界的用法:假设您有一个名为Checker的简单用户控件-它仅包含2个复选框-chkA和chkB。在用户控件中,您可以通过为chkA和ChkB实现相应的事件来控制选中/取消选中事件3.现在,在一个新的WinForm中,当您拖入Checker时...您的目标是确保当chkA单击当您必须更改标签的背景颜色时...lblColorPicker。注意lblColorPicker是一个存在于窗体中的控件,并没有直接绑定到Checker。你将如何实现这个目标?答:首先,您必须为用户控件Checker创建一个新事件。要创建这个新事件,首先在用户控件中创建一个委托,然后使用这个委托作为您正在编写的新事件的定义类型。然后必须将此事件映射到用户控件中的chkA...事件。通过这种方式,您可以通过引用事件来控制chkA...来自任何新表单...通过您刚刚编写的委托。所以,现实世界使用!编写委托时无法实现这一点。如果您不这么认为,或者您需要更多详细说明,请告诉我。在某些情况下,匿名委托使代码更具可读性(您不必转到另一个方法来查看属于您的方法的代码:WinformsexampleclassMyForm:Form{//...protectedoverridevoidOnLoad(EventArge){this.Cursor=Cursors.Wait();this.Enabled=false;//在不阻塞UI线程的情况下执行长时间运行的数据库操作ThreadPool.QueueUserWorkItem(state=>{DoLongDBOperation();//重新启用表单BeginInvoke(newAction(()=>{this.Cursor=Cursors.Default;this.Enabled=true;}));});}如果你向你的类添加事件或做任何不寻常的事情(委托和其他几个很好的理由),委托绝对是必须的。好处是它是一种非常灵活的方法。我假设你指的是定义自定义委托?EventHandler最大限度地减少了对自定义委托定义要求的需求,但如果你想添加它们仍然有用方法签名的附加参数。每当您需要修改或更改winForms控件的任何属性时,您需要使用委托将控制权传递回创建该控件的线程...仅举几个例子之一.一个示例是发布/订阅消息调度程序。您需要向调度程序注册事件,然后适当地调用它们。这使您可以非常轻松地连接不同的代码片段。我想不出不使用委托来做到这一点的方法假设你有一个响应不同按键的控制台应用程序:Actiona=()=>{/*DoStuff*/};Actionb=()=>{/*做事*/};动作c=()=>{/*做事*/};动作d=()=>{/*做事*/};动作e=()=>{/*做事*/};动作f=()=>{/*做事*/};动作g=()=>{/*做事*/};动作h=()=>{/*做事*/};动作i=()=>{/*做事*/};动作j=()=>{/*做事*/};列表操作=newList(){a,b,c,d,e,f,g,h,i,j};弦线;while((line=Console.ReadKey().KeyChar)!='q'){if(line.isBetween_0_and_9()){actions[line.ParseInt()]();显然你可以使用一堆If,但这不仅更容易,而且几乎可以肯定更清晰/可读。以上就是C#学习教程:C#代表实战用法分享的全部内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权请点击右侧联系管理员删除。如需转载请注明出处: