zoukankan      html  css  js  c++  java
  • 3 委托、匿名函数、lambda表达式

     

    在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式

    复制代码
     // 声明一个委托
        delegate void Printer(string s);
        class TestClass
        {
            static void Main()
            {
                //lambda表达式
                Printer pp = x => { 
                    Console.WriteLine("print:" + x);
                };
    
                pp("sky");
    
    
    
                
    //匿名方法的语法:delegate(){//里边是代码块}
    // 摘要:
                //     Initializes a new instance of the System.Threading.Thread class.
                //
                // 参数:
                //   start:
                //     A System.Threading.ThreadStart delegate that represents the methods to be
                //     invoked when this thread begins executing.
                //
                // 异常:
                //   System.ArgumentNullException:
                //     The start parameter is null.
                System.Threading.Thread t1 = new System.Threading.Thread
                  (delegate()
                  {
                      System.Console.Write("Hello, ");
                      System.Console.WriteLine("World!");
                  });
                t1.Start();
    
    
                // 匿名函数
                Printer p = delegate(string j)
                {
                    System.Console.WriteLine(j);
                };
    
                // Results from the anonymous delegate call:
                p("The delegate using the anonymous method is called.");
    
    
    
                // 委托:将方法作为方法的参数
                //下边将方法绑定到委托
                //参考:张子阳的c#委托和事件http://www.cnblogs.com/JimmyZhang/archive/2007/09/23/903360.html
                p = new Printer(TestClass.DoWork);
                p += TestClass.DoWork1;
                // p -= TestClass.DoWork;
                //p -= TestClass.DoWork1;
                // Results from the old style delegate call:
                p("The delegate using the named method is called.");
              
    
            }
    
            // The method associated with the named delegate:
            static void DoWork(string k)
            {
                System.Console.WriteLine(k);
            }
    
            static void DoWork1(string k)
            {
                System.Console.WriteLine(k);
            }
        }

    //无参数的委托
    复制代码
     // 声明一个委托
        delegate void del();
    
        class TestClass
        {
            static void Main()
            {
                del myDelegate1 = () =>
                {
                    Console.WriteLine("00xx");
                };
                myDelegate1();
    
    
                System.Threading.Thread t1 = new System.Threading.Thread
                 (()=>
                 {
                     System.Console.Write("Hello, ");
                     System.Console.WriteLine("World!");
                 });
                t1.Start();
    
    
                 t1 = new System.Threading.Thread
                 (delegate()
                 {
                     System.Console.Write("Hello, ");
                     System.Console.WriteLine("World!");
                 });
                t1.Start();
            }
        }
    复制代码
    
    
    
    
    
    复制代码

    MSDN上的委托例子:

    下面的示例阐释声明、实例化和使用委托。BookDB 类封装一个书店数据库,它维护一个书籍数据库。它公开 ProcessPaperbackBooks 方法,该方法在数据库中查找所有平装书,并对每本平装书调用一个委托。使用的 delegate 类型名为 ProcessBookDelegateTest 类使用该类打印平装书的书名和平均价格。

    委托的使用促进了书店数据库和客户代码之间功能的良好分隔。客户代码不知道书籍的存储方式和书店代码查找平装书的方式。书店代码也不知道找到平装书后将对平装书执行什么处理。

    复制代码
    // A set of classes for handling a bookstore:
    namespace Bookstore
    {
        using System.Collections;
    
        // Describes a book in the book list:
        public struct Book
        {
            public string Title;        // Title of the book.
            public string Author;       // Author of the book.
            public decimal Price;       // Price of the book.
            public bool Paperback;      // Is it paperback?
    
            public Book(string title, string author, decimal price, bool paperBack)
            {
                Title = title;
                Author = author;
                Price = price;
                Paperback = paperBack;
            }
        }
    
        // Declare a delegate type for processing a book:
        public delegate void ProcessBookDelegate(Book book);
    
        // Maintains a book database.
        public class BookDB
        {
            // List of all books in the database:
            ArrayList list = new ArrayList();
    
            // Add a book to the database:
            public void AddBook(string title, string author, decimal price, bool paperBack)
            {
                list.Add(new Book(title, author, price, paperBack));
            }
    
            // Call a passed-in delegate on each paperback book to process it: 
            public void ProcessPaperbackBooks(ProcessBookDelegate processBook)
            {
                foreach (Book b in list)
                {
                    if (b.Paperback)
                        // Calling the delegate:
                        processBook(b);
                }
            }
        }
    }
    
    
    // Using the Bookstore classes:
    namespace BookTestClient
    {
        using Bookstore;
    
        // Class to total and average prices of books:
        class PriceTotaller
        {
            int countBooks = 0;
            decimal priceBooks = 0.0m;
    
            internal void AddBookToTotal(Book book)
            {
                countBooks += 1;
                priceBooks += book.Price;
            }
    
            internal decimal AveragePrice()
            {
                return priceBooks / countBooks;
            }
        }
    
        // Class to test the book database:
        class TestBookDB
        {
            // Print the title of the book.
            static void PrintTitle(Book b)
            {
                System.Console.WriteLine("   {0}", b.Title);
            }
    
            // Execution starts here.
            static void Main()
            {
                BookDB bookDB = new BookDB();
    
                // Initialize the database with some books:
                AddBooks(bookDB);
    
                // Print all the titles of paperbacks:
                System.Console.WriteLine("Paperback Book Titles:");
    
                // Create a new delegate object associated with the static 
                // method Test.PrintTitle:
                bookDB.ProcessPaperbackBooks(PrintTitle);
    
                // Get the average price of a paperback by using
                // a PriceTotaller object:
                PriceTotaller totaller = new PriceTotaller();
    
                // Create a new delegate object associated with the nonstatic 
                // method AddBookToTotal on the object totaller:
                bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);
    
                System.Console.WriteLine("Average Paperback Book Price: ${0:#.##}",
                        totaller.AveragePrice());
            }
    
            // Initialize the book database with some test books:
            static void AddBooks(BookDB bookDB)
            {
                bookDB.AddBook("The C Programming Language", "Brian W. Kernighan and Dennis M. Ritchie", 19.95m, true);
                bookDB.AddBook("The Unicode Standard 2.0", "The Unicode Consortium", 39.95m, true);
                bookDB.AddBook("The MS-DOS Encyclopedia", "Ray Duncan", 129.95m, false);
                bookDB.AddBook("Dogbert's Clues for the Clueless", "Scott Adams", 12.00m, true);
            }
        }
    }
    复制代码

    输出:

    Paperback Book Titles:
       The C Programming Language
       The Unicode Standard 2.0
       Dogbert's Clues for the Clueless
    Average Paperback Book Price: $23.97



    声明委托

    public delegate void ProcessBookDelegate(Book book);

    实例化委托。

    声明了委托类型后,必须创建委托对象并使之与特定方法关联。在上一个示例中,您通过按下面示例中的方式将 PrintTitle 方法传递到 ProcessPaperbackBooks方法来实现这一点:

    bookDB.ProcessPaperbackBooks(PrintTitle);

    这将创建与静态方法 Test.PrintTitle 关联的新委托对象。类似地,对象 totaller 的非静态方法 AddBookToTotal 是按下面示例中的方式传递的:

    bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);

    在两个示例中,都向 ProcessPaperbackBooks 方法传递了一个新的委托对象。

    委托创建后,它的关联方法就不能更改;委托对象是不可变的。

    调用委托。

    创建委托对象后,通常将委托对象传递给将调用该委托的其他代码。通过委托对象的名称(后面跟着要传递给委托的参数,括在括号内)调用委托对象。下面是委托调用的示例:

    processBook(b);

    与本例一样,可以通过使用 BeginInvokeEndInvoke 方法同步或异步调用委托。 

    在C#中使用线程的方法很多,使用委托的BeginInvoke和EndInvoke方法就是其中之一。BeginInvoke方法可以使用线程异步地执行委托所指向的方法。然后通过EndInvoke方法获得方法的返回值(EndInvoke方法的返回值就是被调用方法的返回值),或是确定方法已经被成功调用。我们可以通过四种方法从EndInvoke方法来获得返回值。

    详情:这里

    分析:

    看起来 是不是很像接口啊 给后来着留一个委托 关注返回值和参数

    后来者实现委托 内部可以随便定义东东 但是 返回值和参数必须和委托的一样

    后来者想咋实现就咋实现

    何时使用委托何时使用接口呢 来自MSDN:

    复制代码
    委托和接口都允许类设计器分离类型声明和实现。任何类或结构都能继承和实现给定的接口。可以为任何类上的方法创建委托,前提是该方法符合委托的方法签名。接口引用或委托可由不了解实现该接口或委托方法的类的对象使用。既然存在这些相似性,那么类设计器何时应使用委托,何时又该使用接口呢?
    
    在以下情况下,请使用委托:
    
    当使用事件设计模式时。
    
    当封装静态方法可取时。
    
    当调用方不需要访问实现该方法的对象中的其他属性、方法或接口时。
    
    需要方便的组合。
    
    当类可能需要该方法的多个实现时。
    
    在以下情况下,请使用接口:
    
    当存在一组可能被调用的相关方法时。
    
    当类只需要方法的单个实现时。
    
    当使用接口的类想要将该接口强制转换为其他接口或类类型时。
    
    当正在实现的方法链接到类的类型或标识时:例如比较方法。
    
    使用单一方法接口而不使用委托的一个很好的示例是 IComparable 或泛型版本 IComparable<(Of <(T>)>)。IComparable 声明 CompareTo 方法,该方法返回一个整数,指定相同类型的两个对象之间的小于、等于或大于关系。IComparable 可用作排序算法的基础。虽然将委托比较方法用作排序算法的基础是有效的,但是并不理想。因为进行比较的能力属于类,而比较算法不会在运行时改变,所以单一方法接口是理想的





  • 相关阅读:
    用例图设计
    第二次结队作业
    第一次结对作业
    第二次个人编程作业
    简易的中文语言翻译器
    第一次博客作业
    个人总结
    第三次个人作业——用例图设计
    第二次结对作业
    第一次结对作业
  • 原文地址:https://www.cnblogs.com/hijushen/p/4242647.html
Copyright © 2011-2022 走看看