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

牽著老婆滿街逛

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


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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一区| 蜜乳av另类精品一区二区| 亚洲高清中文字幕| 中文精品视频| 国产女人精品视频| 久久九九免费| 亚洲日本成人网| 亚洲女同性videos| 激情视频一区| 欧美精品粉嫩高潮一区二区| 日韩一级黄色大片| 久久久久国产精品人| 亚洲人成绝费网站色www| 欧美日韩在线免费| 久久成人18免费观看| 亚洲第一区在线观看| 亚洲视频一区二区| 韩国精品在线观看| 欧美另类一区| 欧美一级网站| 99国产精品自拍| 久久亚洲国产成人| 亚洲免费观看在线观看| 国产日韩精品在线观看| 欧美aⅴ一区二区三区视频| 一区二区高清视频| 男人插女人欧美| 亚洲在线一区二区| 亚洲经典一区| 国产欧美日韩不卡| 欧美精品一区二区久久婷婷| 性久久久久久| 99v久久综合狠狠综合久久| 久久免费一区| 亚洲一区二区三区中文字幕| 亚洲福利视频网| 国产欧美大片| 欧美日韩一区精品| 麻豆久久婷婷| 久久成人18免费网站| 这里只有视频精品| 亚洲区免费影片| 男女av一区三区二区色多| 欧美中文字幕不卡| 亚洲视频中文| 99re6热只有精品免费观看 | 欧美成人dvd在线视频| 午夜精品久久久99热福利| 亚洲区欧美区| 欧美国产日韩一区二区| 久久久中精品2020中文| 亚洲欧美日本国产有色| 日韩天堂av| 亚洲国产精品美女| 精品不卡一区二区三区| 国产日韩欧美精品| 国产精品久久一级| 欧美肉体xxxx裸体137大胆| 欧美成人69| 欧美1区2区视频| 另类图片国产| 鲁鲁狠狠狠7777一区二区| 久久精品30| 欧美在线影院| 久久激情综合网| 欧美永久精品| 久久爱www久久做| 欧美一区二区三区在线视频| 新67194成人永久网站| 午夜精品电影| 羞羞漫画18久久大片| 午夜欧美精品久久久久久久| 亚洲主播在线观看| 亚洲欧美日韩精品久久奇米色影视| 一本大道久久a久久精品综合| 亚洲精选视频在线| 日韩视频精品| 宅男在线国产精品| 亚洲欧美中日韩| 香蕉久久夜色精品国产使用方法| 午夜一区二区三区在线观看| 午夜精品在线视频| 久久久久久久久岛国免费| 久久国产一区二区| 美日韩在线观看| 欧美精品久久久久久久久久| 欧美日韩高清免费| 国产精品日本精品| 好看的日韩av电影| 亚洲韩国一区二区三区| 日韩一二三在线视频播| 亚洲午夜精品福利| 久久av二区| 蜜桃av一区二区| 亚洲精品久久久久久久久久久| 99精品福利视频| 亚洲欧美综合国产精品一区| 性伦欧美刺激片在线观看| 久久久一区二区三区| 欧美国产日韩精品免费观看| 国产精品国产三级欧美二区| 国产精一区二区三区| 亚洲丶国产丶欧美一区二区三区| 日韩视频精品在线观看| 亚洲欧美精品伊人久久| 久久精品视频播放| 亚洲电影在线播放| 亚洲在线免费视频| 欧美1级日本1级| 国产精品区二区三区日本 | 亚洲少妇自拍| 久久久久欧美精品| 亚洲国产精品久久久久秋霞不卡 | 欧美一级久久| 欧美日韩国产a| 国产一区观看| 中日韩高清电影网| 久久五月激情| aa成人免费视频| 久久天堂精品| 国产精品入口尤物| 亚洲精品影视在线观看| 欧美一乱一性一交一视频| 亚洲二区精品| 欧美在线视频在线播放完整版免费观看| 欧美成人精品不卡视频在线观看| 国产精品乱码久久久久久| 亚洲日韩欧美视频一区| 久久成人资源| 一本色道久久加勒比精品| 久久婷婷av| 国产日韩欧美三区| 一区二区三区视频在线观看| 美日韩在线观看| 亚洲欧美日韩国产中文在线| 欧美日韩精品综合在线| 亚洲国产乱码最新视频| 欧美在线日韩| 亚洲视频中文| 欧美日韩伦理在线免费| 亚洲国产精品一区在线观看不卡 | 欧美成人a视频| 香蕉成人伊视频在线观看| 欧美日韩在线另类| 亚洲毛片在线观看.| 欧美a级一区| 久久国产免费看| 国产日韩在线一区二区三区| 亚洲一区二区在线免费观看视频 | 亚洲视频在线观看三级| 欧美大片一区二区三区| 亚洲国产精品99久久久久久久久| 久久精品国产亚洲高清剧情介绍| 在线综合亚洲| 国产精品高潮视频| 在线中文字幕一区| 亚洲精品视频一区| 欧美精品一区三区| 日韩写真在线| 亚洲精品乱码久久久久久久久| 欧美xart系列高清| 亚洲伦伦在线| 亚洲精品日韩激情在线电影| 欧美成人有码| 在线视频免费在线观看一区二区| 亚洲日韩欧美视频一区| 欧美日本精品| 亚洲午夜在线观看| 在线亚洲精品| 国产精品无人区| 久久久久国产精品一区三寸| 欧美影院成人| 亚洲第一网站| 亚洲精品视频二区| 国产精品v日韩精品| 亚洲欧美日韩精品久久久| 亚洲专区在线| 国产一区二区三区免费观看| 久久蜜桃资源一区二区老牛| 久久看片网站| 日韩午夜三级在线| 亚洲综合国产精品| 国产综合视频在线观看| 欧美不卡三区| 欧美日韩免费观看一区=区三区| 亚洲午夜激情免费视频| 亚洲欧美日韩在线综合| 樱桃成人精品视频在线播放| 亚洲成色www8888| 欧美丝袜第一区| 久久久夜夜夜| 欧美激情综合网| 欧美一级视频| 蜜桃av噜噜一区| 亚洲欧美日韩国产另类专区|