委托
来源:互联网 发布:罗马全面战争 mac 编辑:程序博客网 时间:2024/06/03 05:07
什么是委托?简单说就是把方法作为参数传给另一个方法。在有些时候,我们对方法的操作并不是针对数据进行的,而是要对另一个方法进行,但我们又不知道这个方法什么,只有在运行的时候才会知道,这时候我们就需要委托。
C#中的委托定义 delegate void MyDelegate();其语法类似于方法的定义,但没有方法体,需要在前面加上关键字delegate.定义一个委托相当于定义一个新类,所有委托具体类的特征。下面一个简单的委托示例:
private delegate string GetString();
static void Main()
{
int x=40;
GetString firstMethod=new GetString(x.ToString);
Consle.WriteLine("String is {0}"+firstMethod());
}
实例化委托现有如下几种方式:
1.GetString firstMethod=new GetString(x.ToString); //最标准的
2.GetString firstMethod=x.ToString;//在C#2.0后的版本,编译器会自动检测类型,成为委托推断。注意,这里不能用 x.ToString() 只能传方法地址,不能传字符串对象。
3.GetString firstMethod=delegate(string x){return x.ToString} //这种称为匿名方法,减少了代码的数量,使用很方便。但这种方法的效率相对是不如前2种的,因为在执行时,编译器还是会自动帮我们定义一个方法。
4.GetString firstMethod=(string x)=>{return x.ToString();}// C#3.0新特性,表达式定义委托。
委托可以包含多个方法,这种委托称为多播委托,例如:
GetString firstMethod=x=>x*2;
GetString secondMethod=x=>x*x;
GetString thirdMethod=firstMethod+secondMethod;
或者也可以写成 GetString thirdMethod=x=>x*2;thirdMethod+=x=>x*x;
在对多播委托调用时,最好手动循环调用里面的每个委托,且用try catch包起来,否则多播委托会按顺序执行,但第一个委托有异常时,后面的委托将不会执行;
因为委托是按类来定义的,所以委托也有数组,例如:
GetString[] thirdMethod={firstMethod,secondMethod};
委托不关心方法的参数,所以会存在委托调用的方法与委托声明的类型不一致,这时就会出现协变和抗变。
协变:方法的返回类型可以派生与委托定义的类型。如:
public class DelegateReturn { }
public class DelegateReturn2 : DelegateReturn { } //DelegateReturn2 派生DelegateReturn
public delegate DelegateReturn MyDelegate1(); //委托MyDelegate1定义方法返回Delega teReturn
class Program {
static void Main() { MyDelegate1 d1 = Method1; d1(); }
static DelegateReturn2 Method1() { DelegateReturn2 d2 = new DelegateReturn2();
return d2; } //方法却返回DelegateReturn2 ,
}
抗变:委托定义的参数不同与调用方法的参数;如:
public class DelegateParam { }
public class DelegateParam2 : DelegateParam { } //DelegateParam2派生于DelegateParam
public delegate void MyDelegate2(DelegateParam2 p); //参数为DelegateParam2
class Program {
static void Main() { MyDelegate2 d2 = Method2; DelegateParam2 p = new DelegateParam2(); d2(p); }
static void Method2(DelegateParam p) { } //这里却是DelegateParam
}