青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴以律己,寬以待人. 三思而后行.
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 楊粼波 閱讀(346) 評論(0)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产深夜精品| 欧美成人亚洲成人| 狠狠色狠色综合曰曰| 免费人成精品欧美精品| 亚洲美女在线一区| 亚洲欧洲av一区二区三区久久| 国产日韩亚洲欧美精品| 欧美国产在线视频| 久久在线免费观看| 欧美日韩在线播放一区| 久久精品国产精品亚洲综合| 亚洲激情第一页| 久久久综合激的五月天| 午夜国产精品影院在线观看 | 亚洲视频axxx| 99成人在线| 国产真实乱偷精品视频免| 国产精品夜色7777狼人| 激情丁香综合| 蜜桃av噜噜一区| 欧美激情一区二区三区在线| 欧美另类综合| 国产一区二区精品久久91| 影音先锋久久精品| 一区二区三区 在线观看视| 亚洲欧美日韩国产精品| 久久天堂精品| 国产精品久久久久国产a级| 国产女人aaa级久久久级| 在线观看欧美日韩| 亚洲午夜未删减在线观看| 久久精品毛片| 一区二区黄色| 欧美久久久久久| 伊甸园精品99久久久久久| 一区二区三区色| 亚洲国产精品va在线看黑人动漫| 亚洲欧美国产视频| 欧美午夜精品一区| 99精品国产在热久久| 欧美成人在线网站| 久久久女女女女999久久| 国产一区二区中文| 久久精品男女| 久久成人免费| 精品999成人| 老司机免费视频久久| 欧美在线www| 国产在线成人| 午夜精品福利在线观看| 久久久久久久一区二区| 亚洲一区尤物| 欧美日韩一区二区三区视频| 亚洲一区在线视频| 欧美电影免费观看网站| 欧美电影在线观看完整版| 国产日韩综合一区二区性色av| 夜夜嗨av一区二区三区免费区| 欧美午夜免费电影| 免费欧美在线| 亚洲视频精选| 亚洲视频碰碰| 老司机一区二区三区| 伊人精品成人久久综合软件| 亚洲第一精品电影| 欧美午夜视频| 亚洲第一毛片| 在线日韩中文| 欧美一级久久| 午夜精品久久久久久久99樱桃| 久久综合九色综合网站| 久久gogo国模啪啪人体图| 欧美日韩国产在线看| 亚洲黄色在线观看| 欧美日韩成人激情| 亚洲国产日韩欧美| 亚洲日本国产| 欧美日韩不卡| 一区二区三区高清在线| 99伊人成综合| 欧美日韩精品系列| 亚洲美洲欧洲综合国产一区| 日韩视频专区| 亚洲欧美在线x视频| 亚洲性夜色噜噜噜7777| 99视频在线观看一区三区| 欧美大胆成人| 你懂的国产精品| 欧美人成在线视频| 亚洲桃色在线一区| 亚洲精品一区二区网址| 欧美一区二粉嫩精品国产一线天| 免费日韩成人| 在线播放国产一区中文字幕剧情欧美| 欧美成人69av| 亚欧成人精品| 亚洲欧洲日本国产| 91久久精品日日躁夜夜躁国产| 午夜精品亚洲一区二区三区嫩草| 久久九九有精品国产23| 亚洲第一黄色| 亚洲一区综合| 国模私拍一区二区三区| 在线一区二区视频| 免费成人av在线看| 在线一区日本视频| 激情欧美一区二区| 欧美视频不卡| 久久久久久噜噜噜久久久精品| 亚洲日本va在线观看| 久久久91精品| 亚洲欧美日韩国产综合在线| 亚洲精品国产精品乱码不99| 国产精品视频一二| 欧美日韩在线播| 亚洲老司机av| 亚洲国产一区二区在线| 免费亚洲视频| 免费成人av在线| 毛片精品免费在线观看| 午夜老司机精品| 欧美在线亚洲在线| 亚洲欧美综合国产精品一区| 亚洲综合不卡| 欧美一级播放| 久久久久久伊人| 蜜桃av一区二区| 久久综合久久综合久久| 久久久久久亚洲精品不卡4k岛国| 欧美一区二区三区免费观看视频| 亚洲愉拍自拍另类高清精品| 亚洲男女自偷自拍| 午夜一区在线| 久久婷婷人人澡人人喊人人爽| 久久久7777| 欧美无乱码久久久免费午夜一区| 欧美日韩一区三区| 亚洲国内自拍| 亚洲专区一区| 免费看av成人| 国产精品入口麻豆原神| 尤物在线观看一区| 一区二区日韩伦理片| 美腿丝袜亚洲色图| 亚洲精品小视频| 久久精品亚洲乱码伦伦中文 | 开元免费观看欧美电视剧网站| 亚洲第一中文字幕在线观看| 亚洲免费视频网站| 欧美精品在线观看一区二区| 激情六月婷婷综合| 欧美一区二区高清| 在线中文字幕日韩| 欧美日韩国产区一| 亚洲日本中文字幕| 老司机精品福利视频| 久久精品国产免费| 国内成人自拍视频| 美女91精品| 老妇喷水一区二区三区| 在线日韩成人| 亚洲国产一区二区a毛片| 免费成人黄色| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 欧美一级专区免费大片| 免费不卡欧美自拍视频| 亚洲电影自拍| 欧美成人午夜剧场免费观看| 久久精品国产一区二区电影| 伊人精品视频| av成人手机在线| 亚洲专区在线视频| 久久精品av麻豆的观看方式 | 亚洲国产一区二区在线| 亚洲电影中文字幕| 在线播放中文一区| 久久精品亚洲热| 裸体一区二区三区| 影音先锋欧美精品| 女人天堂亚洲aⅴ在线观看| 免费在线一区二区| 亚洲六月丁香色婷婷综合久久| 欧美 日韩 国产一区二区在线视频| 香蕉乱码成人久久天堂爱免费| 国产精品高潮呻吟久久av黑人| 中文久久乱码一区二区| 欧美中文日韩| 亚洲黄色毛片| 国产精品毛片大码女人| 久久久五月天| 亚洲一区二区在线播放| 蜜臀久久久99精品久久久久久| 亚洲精品久久久一区二区三区| 欧美日韩精品中文字幕| 亚洲欧美激情一区二区| 欧美高潮视频| 久久精品视频在线看| 9色国产精品| 精品成人一区二区| 国产精品嫩草99av在线|