C#基础——委托
委托是一种引用方法类型。一旦为委托分配了方法,委托将与方法具体完全相同的行为。委托方法调用可以像其他任何方法一样,具有参数和返回值。
与委托的签名(由返回类型和参数组成)匹配的任何可访问类或结构中的任何方法都可以分配给该委托。方法可以是静态方法,也可以是实例方法。这样就可以通过编程方式来改方法的调用。还可以向现有的类中插入新代码。只要知道委托的签名,便可以分配自己委托的方法。
委托具有以下特点:
1、委托类似于C++函数指针,但它们是类型安全的。
2、委托允许将方法作为参数进行传递。
3、委托可以用于定义回调方法。
4、委托可以链接在一起,可以对一个事件调用多个方法。
5、方法不必与委托签名完全匹配(委托中的协变和逆变)
6、C#2.0后引入匿名方法,此方法允许将代码块作为参数传递,以代替单独定义的方法。
示例1、简单示例:
-
public delegate void Del(string message); public class Program { public static void DelegateMethod(string msg) { Console.WriteLine(msg); } public static void MethodCallBack(int param1,int param2,Del callback) { callback("The number is: " + (param1 + param2).ToString()); } public static void Main() { Del handler=DelegateMethod; MethodCallBack(1,2,handler); Console.ReadLine(); } }
输出:
示例2、命名方法示例:
-
public delegate void Del(int i,double j); public class Program { void MultiplyNumbers(int m,double n) { Console.Write(m*n+" "); } public static void Main() { Program p=new Program(); Del d=p.MultiplyNumbers; Console.WriteLine("Invoking the delegate using 'MultiplyNumbers':"); for (int i = 1; i <= 5; i++) { d(i, 2); } Console.ReadLine(); } }
输出:
示例3、委托被同时映射到静态方法和实例方法,并分别返回特定的信息。
-
delegate void Del(); class SampleClass { public void InstanceMethod() { Console.WriteLine("the instance method"); } public static void StaticMethod() { Console.WriteLine("this static method"); } } public class Program { public static void Main() { SampleClass sc=new SampleClass(); Del d=sc.InstanceMethod; d(); d=SampleClass.StaticMethod; d(); Console.ReadLine(); } }
输出:
示例4、委托协办
-
public class Vehicle { } public class Car:Vehicle { } public class Program { public delegate Vehicle HandlerMethod(); public static Vehicle VihicleHandler() { Console.WriteLine("Return Vehicle"); return null; } public static Car CarHandler() { Console.WriteLine("Return Car"); return null; } public static void Main() { HandlerMethod h1=VihicleHandler; h1(); HandlerMethod h2=CarHandler; h2(); Console.ReadLine(); } }
输出:
示例5、合并委托
-
delegate void Del(string s); public class Program { static void Hello(string s) { Console.WriteLine(" Hello,{0}",s); } static void Goodbye(string s) { Console.WriteLine(" Goodbye,{0}",s); } public static void Main() { Del a,b,c,d; a=Hello; b=Goodbye; c=a+b; 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"); Console.ReadLine(); } }
输出:
示例5、综合示例
-
namespace Bookstore { public struct Book { public string Title; public string Author; public decimal Price; public bool Pagerback; public Book(string title,string author,decimal price,bool pagerback) { this.Title=title; this.Author=author; this.Price=price; this.Pagerback=pagerback; } } public delegate void ProcessBookDelegate(Book book); public class BookDB { ArrayList list=new ArrayList(); public void AddBook(string title,string author,decimal price,bool pagerback) { list.Add(new Book(title,author,price,pagerback)); } public void ProcessPaperbackBooks(ProcessBookDelegate processBook) { foreach (Book b in list) { if (b.Pagerback) processBook(b); } } } } namespace BookTestClient { using Bookstore; 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; } } public class Program { static void PrintTitle(Book b) { Console.WriteLine(" {0}",b.Title); } 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); } public static void Main() { BookDB bookDB=new BookDB(); AddBooks(bookDB); Console.WriteLine("Paperback Book Titles:"); bookDB.ProcessPaperbackBooks(PrintTitle); PriceTotaller totaller = new PriceTotaller(); bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal); Console.WriteLine("Average Paperback Book Price: ${0:#.##}", totaller.AveragePrice()); Console.ReadLine(); } } }
输出: