inforasc

美好的每一天

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

委托是一种数据结构,它引用静态方法或者引用类实例及该类的实例方法(MSDN);

委托类型的声明,建立了一个协定,该协定指向一个或者多个方法的签名;

委托是面向对象并且是类型安全的。

一、Delegate的简单例子:

委托的声明需要使用关键字:delegate;

委托的命名是任意的,但是委托必须与它指向的方法签名相匹配:返回类型;参数个数与类型

namespace ConsoleApplication1
{

    //定义委托,可以指向任何这样的方法:返回值 为 Int型,并且有两个Int参数
   
public delegate int MathDelegate(int x,int y);
    public classDelegateDemo
  
{
        public static int Add(int x, int y)
        {
            returnx + y;
        }
        public static int Multiply(int x, int y)
        {
            returnx * y;
        }
        public static int Subtract(int x, int y)
        {
            returnx - y;
        }
    }
    public classProgram
  
{

        static voidMain(string[] args)
        {
            //创建一个委托实例,指向DelegateDemo.Add()方法
            
MathDelegate math1 = newMathDelegate(DelegateDemo.Add);
            //调用Add()使用委托
           
Console.WriteLine("100 + 20 = {0}", math1(100, 20));
            //创建一个委托实例,指向DelegateDemo.Multiply()方法
           
MathDelegate math2 = newMathDelegate(DelegateDemo.Multiply);
            Console.WriteLine("100 * 20 = {0}", math2(100, 20));

            Console.ReadLine();
        }

    }
}

二、委托的多播(Multicast)

多播是指一个委托对象可以指向多个方法,而不是仅仅是指向一个方法;

采用 += 添加方法,-= 移走方法

多播委托指向的方法的 返回值 一般是void,当然如果有返回值的话,那么仅能得到最后一个方法的返回值

 

namespace ConsoleApplication1
{

//定义委托,可以指向任何这样的方法:返回值 为 Int型,并且有两个Int参数
public delegate int MathDelegate(int x,int y);
public class DelegateDemo
{
public static int Add(int x, int y)
{
Console.WriteLine("加法的结果:");
Console.WriteLine("{0} + {1} = {2}\n", x, y, x + y);

return x + y;
}
public static int Multiply(int x, int y)
{
Console.WriteLine("乘法的结果:");

Console.WriteLine("{0} * {1} = {2}\n", x, y, x * y);

return x * y;
}
public static int Subtract(int x, int y)
{
Console.WriteLine("减法的结果:");

Console.WriteLine("{0} - {1} = {2}\n", x, y, x - y);

return x - y;
}
}
public class Program
{

static void Main(string[] args)
{
//创建一个委托实例,指向DelegateDemo.Add()方法
MathDelegate math = new MathDelegate(DelegateDemo.Add);
//使用上述创建的相同的实例,调用DelegateDemo.Multiply()方法 和 DelegateDemo.Subtract()方法
math += new MathDelegate(DelegateDemo.Multiply);
math += new MathDelegate(DelegateDemo.Subtract);

int result = math(100, 20);
Console.WriteLine("委托调用结果:{0}",result);

Console.ReadLine();
}

}
}

三、委托协变和逆变

将方法签名与委托类型匹配时,协变和逆变可以提供一定程度的灵活性;

协变允许方法具有的派生返回类型比委托中定义的更多;

逆变允许方法具有的派生参数类型比委托类型中的更少;(MSDN)

namespace ConsoleApplication1
{
public delegate Person PersonDelegate();
public class DelegateCovariance
{
public static Person GetPerson()
{
return new Person();
}

public static Student GetStudent()
{
return new Student();
}
static void Main(string[] args)
{
PersonDelegate personDelegate = new PersonDelegate(GetPerson);

Person person = personDelegate();
Console.WriteLine("Person:{0}", person.ToString());

PersonDelegate studentDelegate = new PersonDelegate(GetStudent);

Student student = (Student)studentDelegate();//如果没有强类型转换,则不能通过编译 Console.WriteLine("Student:{0}", student.ToString());

Console.ReadLine();
}
}

public class Person
{
protected string _firstName;
protected string _lastName;
protected int _age;

public Person()
{
this._firstName = "Smith";
this._lastName = "Jack";
this._age = 20;
}
public override string ToString()
{
return string.Format("FirstName:{0}\tLastName:{1}\tAge:{2}", _firstName, _lastName, _age);
}
}
public class Student : Person
{
protected string _height;
public Student()
: base()
{
_height = "175cm";
}
public override string ToString()
{
return string.Format("FirstName:{0}\tLastName:{1}\tAge:{2}\tHeight:{3}", _firstName, _lastName, _age, _height);
}
}
}
通过基础简单例子的撰写,对委托的基础知识可以牢固的掌握,下一节主要是学习 委托的异步调用

结束

 


 

posted on 2009-10-14 22:39  inforasc  阅读(981)  评论(0编辑  收藏  举报