zoukankan      html  css  js  c++  java
  • C# delegate

    .Net 中的委托类似于 C 或 C++ 中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与 C 或 C++ 中的函数指针不同,委托是面向对象、类型安全的,并且是安全的。

      委托声明定义一种类型,它用一组特定的参数以及返回类型封装方法。对于静态方法,委托对象封装要调用的方法。对于实例方法,委托对象同时封装一个实例和该实例上的一个方法。如果您有一个委托对象和一组适当的参数,则可以用这些参数调用该委托。委托的一个有趣且有用的属性是,它不知道或不关心自己引用的对象的类。任何对象都可以;只是方法的参数类型和返回类型必须与委托的参数类型和返回类型相匹配。这使得委托完全适合“匿名”调用。

          在任何地方都可以使用Delegates
    在这一点上,也许你只知道有这样一回事,但却没有察觉它在你的程序中的应用。虽然你没有建立自己的delegates,但如果经常使用事件时你会使用到它们。一个极好的例子就是ASP.NET中使用的事件。在后台使用的Delegates围绕着事件工作。事件使用一个标记,你也可以在一个线程结构中找到delegates。

    Delegate 和 interface

    你必须注意的另一个点是一个delegate和一个接口之间的相似性,因为它们都将规范和执行分离开来。它们允许开发人员建立与规范相符合的执行。除此之外,方法标记必须是被指定和相兼容。

    所以,你什么时候使用接口?以及你什么时候使用delegates?微软提供了以下的指导思想。

    Delegates:
    调用一个单一方法。 一个类要进行方法规范(method specification)的多种执行。 使用一个静态方法来执行规范。 想获得类似事件设计的模式。 调用者没有必要知道或获得方法定义的对象。 执行的提供者想将规范的执行“分发”成一些选择性的部分。

    interface:

    规范指定一套即将被调用的方法。 特别的,一个类只执行规范一次。 接口的调用者想通过接口类型以获得其它接口或类。

    下面我们用示例来理解一下吧!.....................O(∩_∩)O

    示例1

    BookDB是一个书籍数据库、他公开了ProcessPaperbackBooks 方法、并且每本平装书都调用一个委托ProcessBookDelegate、从而得到书籍标题和平均价格

    Code

     1 using System;
    2 namespace Bookstore
    3 {
    4 using System.Collections;
    5 public struct Book
    6 {
    7 public string Title; //标题
    8 public string Author; // 作者
    9 public decimal Price; // 价格
    10 public bool Paperback; // 是否是平装书籍
    11 public Book(string title, string author, decimal price, bool paperBack)
    12 {
    13 Title = title;
    14 Author = author;
    15 Price = price;
    16 Paperback = paperBack;
    17 }
    18 }
    19 //声明委托 参数是book
    20 public delegate void ProcessBookDelegate(Book book);
    21
    22 // 模拟书籍数据库
    23 public class BookDB
    24 {
    25 ArrayList list = new ArrayList();
    26 //添加
    27 public void AddBook(string title, string author, decimal price, bool paperBack)
    28 {
    29 list.Add(new Book(title, author, price, paperBack));
    30 }
    31 // 处理平装书籍
    32 public void ProcessPaperbackBooks(ProcessBookDelegate processBook)
    33 {
    34 foreach (Book b in list)
    35 {
    36 if (b.Paperback)//过滤平装书籍
    37 processBook(b);
    38 }
    39 }
    40 }
    41 }
    42 //书籍平均价格
    43 namespace BookTestClient
    44 {
    45 using Bookstore;
    46 class PriceTotaller
    47 {
    48 int countBooks = 0;
    49 decimal priceBooks = 0.0m;
    50 internal void AddBookToTotal(Book book)
    51 {
    52 countBooks += 1;
    53 priceBooks += book.Price;
    54 }
    55 internal decimal AveragePrice()
    56 {
    57 return priceBooks / countBooks;
    58 }
    59 }
    60 class Test
    61 {
    62 //打印评价书籍标题
    63 static void PrintTitle(Book b)
    64 {
    65 Console.WriteLine(" {0}", b.Title);
    66 }
    67 static void Main()
    68 {
    69 Console.WriteLine("创建书籍数据库");
    70 BookDB bookDB = new BookDB();
    71 AddBooks(bookDB);
    72 Console.WriteLine("增加书籍完毕");
    73 Console.WriteLine("所有平装书名");
    74 bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(PrintTitle));
    75 PriceTotaller totaller = new PriceTotaller();
    76 bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(totaller.AddBookToTotal));
    77 Console.WriteLine("评价书籍平均价格是: ${0:#.##}",
    78 totaller.AveragePrice());
    79 }
    80 static void AddBooks(BookDB bookDB)
    81 {
    82 bookDB.AddBook("C# 设计模式","X.Y", 19.95m, true);
    83 bookDB.AddBook("人月神话 ","X.Y", 39.95m, true);
    84 bookDB.AddBook("大话设计模式", "X.Y", 129.95m, false);
    85 bookDB.AddBook("精通C#", "X.Y", 12.00m, true);
    86 }
    87 }
    88 }

    效果图

     示例2

     委托是可以用"+"和"-"来添加和移除的、但是要满足两个条件。条件一:必须是相同类型的委托、条件二:必须都是void返回值

    Code

     1 using System;
    2 delegate void MyDelegate(string s);
    3 class MyClass
    4 {
    5 public static void Hello(string s)
    6 {
    7 Console.WriteLine(" Hello, {0}!", s);
    8 }
    9 public static void Goodbye(string s)
    10 {
    11 Console.WriteLine(" Goodbye, {0}!", s);
    12 }
    13 public static void Main()
    14 {
    15 MyDelegate a, b, c, d;
    16
    17 a = new MyDelegate(Hello);
    18
    19 b = new MyDelegate(Goodbye);
    20
    21 c = a + b;
    22
    23 d = c - a;
    24 Console.WriteLine("调用 delegate a:");
    25 a("A");
    26 Console.WriteLine("调用 delegate b:");
    27 b("B");
    28 Console.WriteLine("调用 delegate c:");
    29 c("C");
    30 Console.WriteLine("调用 delegate d:");
    31 d("D");
    32 }
    33 }

    效果图

    人生如棋、我愿为卒、行动虽缓、从未退过

    03 2012 档案

     
    摘要: 概述索引器允许类或结构的实例就像数组一样进行索引。索引器类似于属性,不同之处在于它们的访问器采用参数。在下面的示例中,定义了一个泛型类,并为其提供了简单的 get和 set访问器方法(作为分配和检索值的方法)。Program类为存储字符串创建了此类的一个实例。Code 1 class SampleCollection<T> 2 { 3 // Declare an array to store the data elements. 4 private T[] arr = new T[100]; 5 6 // Define the indexer, which will ...阅读全文
    posted @ 2012-03-24 19:02 《孙金棚的程序人生》 阅读(35) | 评论 (0) 编辑
     
    摘要: .Net中的委托类似于 C 或 C++ 中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与 C 或 C++ 中的函数指针不同,委托是面向对象、类型安全的,并且是安全的。 委托声明定义一种类型,它用一组特定的参数以及返回类型封装方法。对于静态方法,委托对象封装要调用的方法。对于实例方法,委托对象同时封装一个实例和该实例上的一个方法。如果您有一个委托对象和一组适当的参数,则可以用这些参数调用该委托。委托的一个有趣且有用的属性是,它不知道或不关心自己引用的对象的类。任何对象都可以;只是方法的参数类型..阅读全文
    posted @ 2012-03-24 18:00 《孙金棚的程序人生》 阅读(725) | 评论 (4) 编辑
     
    摘要: 1、概念设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。2、一个模式的四个基本要素综述 设计模式使人们可以更加简单方便地复用成功的设计和体系结构。将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。模式名称(pattern name) 一个助记名,它用一两个词来描述模式的问题、解决方案和效果。命名一个新的模式增加了我..阅读全文
    posted @ 2012-03-22 14:01 《孙金棚的程序人生》 阅读(303) | 评论 (4) 编辑
     
    摘要: 官网:http://www.appelsiini.net/projects/jeditable示例:http://www.appelsiini.net/projects/jeditable/default.html什么是即时编辑?一般的流程是这样的,当用户点击网页上的文字时,该文字就会出现在一个编辑框中,用户对文字进行修改完成后点击提交按钮,新的文本将发送到服务器上,然后表单消失,显示最新编辑的文本。基本的使用方法如下:首先编辑一个 html 文件,包含这么一段:1 2 <div class="edit" id="div_1">Dolor&l阅读全文
    posted @ 2012-03-22 11:43 《孙金棚的程序人生》 阅读(43) | 评论 (1) 编辑
     
    摘要: 就一个简单的Table,开始我们的钻研<tableid="DetailInfo"><tbody><tr> <th > <input id="chbAll" type="checkbox" onclick="fnSelectAll(this);" /></th><th>标题1</th><th>标题2</th><th>标题3<阅读全文
    posted @ 2012-03-19 16:38 《孙金棚的程序人生》 阅读(32) | 评论 (0) 编辑
     
    摘要: 一、基础1、说明:创建数据库CREATE DATABASE database-name 2、说明:删除数据库drop database dbname3、说明:备份sql server--- 创建 备份数据的 deviceUSE masterEXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'--- 开始 备份BACKUP DATABASE pubs TO testBack 4、说明:创建新表create table tabname(col1 type1 [阅读全文
    posted @ 2012-03-16 12:58 《孙金棚的程序人生》 阅读(323) | 评论 (2) 编辑
     
    摘要: DECLARE @dt datetimeSET @dt=GETDATE()DECLARE @number intSET @number=1--1.指定日期该年的第一天或最后一天--第一天为月日、最后一天为月日都是固定的 --A. 年的第一天 SELECT CONVERT(char(5),@dt,120)+'1-1'AS '年第一天' --B. 年的最后一天 SELECT CONVERT(char(5),@dt,120)+'12-31'AS '年最后一天'--2.指定日期所在季度的第一天或最后一天 --A. 季度的第一天 SELEC阅读全文
    posted @ 2012-03-15 14:19 《孙金棚的程序人生》 阅读(115) | 评论 (0) 编辑
  • 相关阅读:
    【C++】C++中的流
    【C++】C++中类的基本使用
    【Python】解析Python中的条件语句和循环语句
    【C++】C++中的分离式编译
    【C++】C++中assert和ENDEGU预处理语句
    【C++】C++中的函数的基本使用
    【算法】解析IEEE 754 标准
    【ThinkPHP】解析ThinkPHP5创建模块
    【C++】C++中的迭代器
    【算法】解析位运算
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2417186.html
Copyright © 2011-2022 走看看