委托



        委托听名字感觉蛮有意思,大概意思是把事情托付给他人完成。

1  委托的基本介绍

        委托的由来也许是 C++中的函数指针,但它具有函数指针的类型的功能,使用委托实例调用方法。委托是一种类型,用来定义函数的签名(返回值在这里作为签名的一部分)。由此,不妨这样理解,定义了某种委托,该委托确定了方法的签名,如下所示。



        public delegate void MyString(string s);

        使用delegate关键词定义了MyString委托,该委托访问权限为 public,其确定的方法的返回类型为空,接收一个字符串参数。


        然后将该委托实例化为对象,而对象是需要初始化的,由此则将与由委托确定的方法相同签名的方法赋值给该委托,如下所示。


        定义了两个域委托定义一致的方法。

         public static void Myfuction1(string s)
        {
            Console.WriteLine("f1:" + s);
        }

        public static void Myfuction2(string s)
        {
            Console.WriteLine("f2:" + s);
        }

        接着实例化委托,并赋值。

            MyString MS1 = new MyString(Myfuction1);
            MyString MS2 = Myfuction2;

         .net早期版本中,支持的是第一种方式,在后面的版本中,可以直接使用方法对委托实例对象进行“赋值”。


        接下来就可以使用对象去调用被赋值的方法。

            MS1("ni hao!");
            MS2("ni hao!");

        输出结果如下。


f1: ni hao!


f2: ni hao!


        至此,可以知道委托是对方法的引用的类型,可以使用具体方法对其进行实例化,可以使用委托对象调用方法。


2  委托的特性


        委托是一种安全地封装方法的类型,它与 C C++中的函数指针类似。与 C中的函数指针不同,委托是面向对象的、类型安全的和保险的。


        构造委托对象时,通常是使用命名的方法对其进行封装,但也可以使用匿名方法和 Lambda表达式对其进行封装。


        委托类型派生自 .NETFramework中的 Delegate类。委托类型是密封的,不能从 Delegate中派生委托类型,也不可能从中派生自定义类。


        由于实例化委托是一个对象,所以可以将其作为参数进行传递,也可以将其赋值给属性。


        由于委托不需要直接调用控制台,仅只是准备字符串并将字符串传递给其它方法,所以,委托的方法可以使用任意数量的参数。


        委托不仅可以引用实例方法,而且可以引用静态方法。当引用实例方法时,将同时引用实例和方法,当引用静态方法时,只引用方法。


3  委托的简单应用


        在下面的实例中定义了书本结构,接着定义了处理书本的委托,定义了书店类,在书店类中定义了方法,并将委托作为方法参数传递给方法,并在方法中调用委托。然后,分别定义了实例方法和静态方法用以处理书本,在类 program中实例化对象,并将方法“赋值”给委托,当调用方法时,便完成了相应书本的处理。

namespace 小书店
{
    public struct Book
    {
        public string Title;        // Title of the book.
        public decimal Price;       // Price of the book.

        public Book(string title, decimal price)
        {
            Title = title;
            Price = price;
        }
    }

    // Declare a delegate type for processing a book:
    public delegate void ProcessBookDelegate(Book book);

    public class BookStore
    {
        Book book = new Book("The C Programming Language", 19.95m);

        public void ProcessBooks(ProcessBookDelegate processBook)
        {
            processBook(book);
        }
    }

    class ConsiderPericIsReasonable
    {
        public void judge(Book b)
        {
            if (b.Price > 20)
            {
                Console.WriteLine("unreasonable");
            }
            else
            {
                Console.WriteLine("reasonable");
            }
        }
    }
    
    class Program
    {
        static void PrintTitle(Book b)
        {
            System.Console.WriteLine("{0}", b.Title);
        }

        static void Main(string[] args)
        {
            BookStore bookDB = new BookStore();
            bookDB.ProcessBooks(PrintTitle);    //静态成员方法的初始化委托

            ConsiderPericIsReasonable consider = new ConsiderPericIsReasonable();
            bookDB.ProcessBooks(consider.judge);    //实例成员方法的初始化委托
        }
    }
}

        输出结果为。


The CProgramming Language


reasonable


        委托的使用使得数据端与客户端之间功能良好的分离,在设计数据时不必考虑客户端对数据的具体处理现实,而客户端同样不需考虑数据具体存取形式。就如上程序,书店类仅只定义了书本处理程序标准,并没有定义具体的实现;打印书本标题、考虑价格是否合理也不需考虑,书店类中书本的存取形式及实现细节。


3  合并委托(多播委托)


        在前面的示例中,一个委托实例对应一个方法,如果将多个方法分配给一个委托实例时,则形成多播委托。


        对多播委托可以使用 ++=或者 --=将方法(或者相同类型的委托实例)添加到委托实例上或从委托实例上移除,当调用多播委托是,会按照添加的顺序调用列表中的方法。


        示例如下(摘取C#编程指南)。

// Define two methods that have the same signature as CustomDel.
    static void Hello(string s)
    {
        System.Console.WriteLine("  Hello, {0}!", s);
    }

    static void Goodbye(string s)
    {
        System.Console.WriteLine("  Goodbye, {0}!", s);
    }

    static void Main()
    {
        // Declare instances of the custom delegate.
        CustomDel hiDel, byeDel, multiDel, multiMinusHiDel;

        // In this example, you can omit the custom delegate if you 
        // want to and use Action<string> instead.
        //Action<string> hiDel, byeDel, multiDel, multiMinusHiDel;

        // Create the delegate object hiDel that references the
        // method Hello.
        hiDel = Hello;

        // Create the delegate object byeDel that references the
        // method Goodbye.
        byeDel = Goodbye;

        // The two delegates, hiDel and byeDel, are combined to 
        // form multiDel. 
        multiDel = hiDel + byeDel;

        // Remove hiDel from the multicast delegate, leaving byeDel,
        // which calls only the method Goodbye.
        multiMinusHiDel = multiDel - hiDel;

        Console.WriteLine("Invoking delegate hiDel:");
        hiDel("A");
        Console.WriteLine("Invoking delegate byeDel:");
        byeDel("B");
        Console.WriteLine("Invoking delegate multiDel:");
        multiDel("C");
        Console.WriteLine("Invoking delegate multiMinusHiDel:");
        multiMinusHiDel("D");
    }
}

        输出如下。


Invoking delegate hiDel:


 Hello, A!


Invoking delegate byeDel:


 Goodbye, B!


Invoking delegate multiDel:


 Hello, C!


 Goodbye, C!


Invoking delegate multiMinusHiDel:


 Goodbye, D!


4  委托的高级应用——事件


        这一部分将在下一篇中详细陈述。


5  参考


C#编程指南


C#自学手册


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值