• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            委托(Delegate)

            C# 中的委托類似于 C C++ 中的函數指針。使用委托使程序員可以將方法引用封裝在委托對象內。然后可以將該委托對象傳遞給可調用所引用方法的代碼,而不必在編譯時知道將調用哪個方法。與 C C++ 中的函數指針不同,委托是面向對象、類型安全的,并且是安全的。

            委托聲明定義一種類型,它用一組特定的參數以及返回類型封裝方法。對于靜態方法,委托對象封裝要調用的方法。對于實例方法,委托對象同時封裝一個實例和該實例上的一個方法。如果您有一個委托對象和一組適當的參數,則可以用這些參數調用該委托。

            委托的一個有趣且有用的屬性是,它不知道或不關心自己引用的對象的類。任何對象都可以;只是方法的參數類型和返回類型必須與委托的參數類型和返回類型相匹配。這使得委托完全適合匿名調用。

            此教程包括兩個示例:

            示例 1 展示如何聲明、實例化和調用委托。

            示例 2 展示如何組合兩個委托。

            此外,還討論以下主題:

            委托和事件

            委托與接口

            示例 1

            下面的示例闡釋聲明、實例化和使用委托。BookDB 類封裝一個書店數據庫,它維護一個書籍數據庫。它公開 ProcessPaperbackBooks 方法,該方法在數據庫中查找所有平裝書,并為每本書調用一個委托。所使用的 delegate 類型稱為 ProcessBookDelegateTest 類使用該類輸出平裝書的書名和平均價格。

            委托的使用促進了書店數據庫和客戶代碼之間功能的良好分隔。客戶代碼不知道書籍的存儲方式和書店代碼查找平裝書的方式。書店代碼也不知道找到平裝書后將對平裝書進行什么處理。

             

            // bookstore.cs

            using System;

             

            // 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 Test

               
            {

                  
            // Print the title of the book.

                  
            static void PrintTitle(Book b)

                  
            {

                     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:

                     Console.WriteLine(
            "Paperback Book Titles:");

                     
            // Create a new delegate object associated with the static 

                     
            // method Test.PrintTitle:

                     bookDB.ProcessPaperbackBooks(
            new ProcessBookDelegate(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(
            new ProcessBookDelegate(totaller.AddBookToTotal));

                     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.95mtrue);

                     bookDB.AddBook(
            "The Unicode Standard 2.0"

                        
            "The Unicode Consortium"39.95mtrue);

                     bookDB.AddBook(
            "The MS-DOS Encyclopedia"

                        
            "Ray Duncan"129.95mfalse);

                     bookDB.AddBook(
            "Dogbert's Clues for the Clueless"

                        
            "Scott Adams"12.00mtrue);

                  }


               }


            }

             

            輸出

            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);

             

            聲明一個新的委托類型。每個委托類型都描述參數的數目和類型,以及它可以封裝的方法的返回值類型。每當需要一組新的參數類型或新的返回值類型時,都必須聲明一個新的委托類型。

            實例化委托 聲明了委托類型后,必須創建委托對象并使之與特定方法關聯。與所有其他對象類似,新的委托對象用 new 表達式創建。但創建委托時,傳遞給 new 表達式的參數很特殊:它的編寫類似于方法調用,但沒有方法的參數。

            下列語句:

             

            bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(PrintTitle));

             

            創建與靜態方法 Test.PrintTitle 關聯的新的委托對象。下列語句:

             

            bookDB.ProcessPaperbackBooks(new 

               ProcessBookDelegate(totaller.AddBookToTotal));

             

            創建與對象 totaller 上的非靜態方法 AddBookToTotal 關聯的新的委托對象。在兩個例子中,新的委托對象都立即傳遞給 ProcessPaperbackBooks 方法。

            請注意一旦創建了委托,它所關聯到的方法便永不改變:委托對象不可改變。

            調用委托 創建委托對象后,通常將委托對象傳遞給將調用該委托的其他代碼。通過委托對象的名稱(后面跟著要傳遞給委托的參數,括在括號內)調用委托對象。下面是委托調用的示例:

             

            processBook(b);

             

            示例 2

            本示例演示組合委托。委托對象的一個有用屬性是,它們可以+運算符來組合。組合的委托依次調用組成它的兩個委托。只可組合相同類型的委托,并且委托類型必須具有 void 返回值。-運算符可用來從組合的委托移除組件委托。

             

            // compose.cs

            using System;

            delegate void MyDelegate(string s);

            class MyClass

            {

                
            public static void Hello(string s)

                
            {

                    Console.WriteLine(
            "  Hello, {0}!", s);

                }


                
            public static void Goodbye(string s)

                
            {

                    Console.WriteLine(
            "  Goodbye, {0}!", s);

                }


                
            public static void Main()

                
            {

                    MyDelegate a, b, c, d;

                    
            // Create the delegate object a that references 

                    
            // the method Hello:

                    a 
            = new MyDelegate(Hello);

                    
            // Create the delegate object b that references 

                    
            // the method Goodbye:

                    b 
            = new MyDelegate(Goodbye);

                    
            // The two delegates, a and b, are composed to form c, 

                    
            // which calls both methods in order:

                    c 
            = a + b;

                    
            // Remove a from the composed delegate, leaving d, 

                    
            // which calls only the method Goodbye:

                    d 
            = c - a;

                    Console.WriteLine(
            "Invoking delegate a:");

                    a(
            "A");

                    Console.WriteLine(
            "Invoking delegate b:");

                    b(
            "B");

                    Console.WriteLine(
            "Invoking delegate c:");

                    c(
            "C");

                    Console.WriteLine(
            "Invoking delegate d:");

                    d(
            "D");

                }


            }

             

            輸出

            Invoking delegate a:

              Hello, A!

            Invoking delegate b:

              Goodbye, B!

            Invoking delegate c:

              Hello, C!

              Goodbye, C!

            Invoking delegate d:

              Goodbye, D!

            委托和事件

            委托非常適合于用作事件(從一個組件就該組件中的更改通知偵聽器)。

            委托與接口

            委托和接口的類似之處是,它們都允許分隔規范和實現。多個獨立的作者可以生成與一個接口規范兼容的多個實現。類似地,委托指定方法的簽名,多個作者可以編寫與委托規范兼容的多個方法。何時應使用接口,而何時應使用委托呢?

            委托在以下情況下很有用:

            調用單個方法。

            一個類可能希望有方法規范的多個實現。

            希望允許使用靜態方法實現規范。

            希望類似事件的設計模式。

            調用方不需要知道或獲得在其上定義方法的對象。

            實現的提供程序希望只對少數選擇組件分發規范實現。

            需要方便的組合。

            接口在以下情況下很有用:

            規范定義將調用的一組相關方法。

            類通常只實現規范一次。

            接口的調用方希望轉換為接口類型或從接口類型轉換,以獲得其他接口或類。

            posted on 2008-01-07 11:10 楊粼波 閱讀(335) 評論(0)  編輯 收藏 引用

            国产精品热久久无码av| 国产三级久久久精品麻豆三级| 日韩中文久久| 久久99精品久久久久久秒播| 国产欧美一区二区久久| 99re这里只有精品热久久| 久久精品国产清高在天天线| 亚洲va中文字幕无码久久不卡| 久久午夜福利无码1000合集| 久久久久久国产精品无码下载| 狠狠色婷婷久久一区二区| 精品综合久久久久久97| 国产成人久久久精品二区三区| 久久九九久精品国产免费直播| 岛国搬运www久久| 久久美女人爽女人爽| 成人亚洲欧美久久久久| 国内精品久久久久影院日本| 亚洲性久久久影院| 新狼窝色AV性久久久久久| 亚洲精品NV久久久久久久久久| 久久91精品国产91久久户| 精品国产青草久久久久福利| 国产99久久久国产精免费| 国产91久久精品一区二区| 久久香综合精品久久伊人| 久久这里只精品国产99热| 久久久久亚洲AV无码永不| 久久强奷乱码老熟女网站| 伊人情人综合成人久久网小说| 久久免费的精品国产V∧| 欧美日韩久久中文字幕| 久久久这里只有精品加勒比| 久久最新免费视频| 久久综合九色综合网站| 亚洲中文久久精品无码ww16| 东方aⅴ免费观看久久av| 亚洲av日韩精品久久久久久a| 一本色综合网久久| 久久久久人妻一区精品性色av| 久久99精品久久久久子伦|