第十五天
(伟大的人类仍在爬行中……)
第八章:委托、Lambda表达式和事件
8.1引用方法
委托是寻址方法的.NET版本。在C++中,指针是危险的。而委托是类型安全的类,它定义了返回类型和参数的类型,委托类不仅包含对方法的引用,也可以包含对多个方法的引用。
Lambda表达式与委托直接相关。当参数是委托类型时,就可以使用Lambda表达式实现委托引用的方法。
8.2委托
当要把方法传送给其他方法时,需要使用委托:
int i=int.Parse("99");
.NET Framework在语法上不允许使用这种直接方法。如果要传递方法,就必须把方法的细节封装在一种新类型的对象中,即委托。委托只是一种特殊类型的对象,其特殊之处在于,我们以前定义的所有对象都包含数据,而委托包含的只是一个或多个方法的地址
8.2.1声明委托
在C#中使用一个类时,分两个阶段。
首先,需要定义这个类,即告诉编译器这个类由什么字段和方法使用。
然后(除非只使用静态方法),实例化类的一个对象。
使用委托时,也需要经过这两个步骤。
首先必须定义要使用的委托,对于委托,定义它就是告诉编译器这种类型的委托表示哪种类型的方法。
然后必须创建该委托的一个或多个实例。
定义委托的语法:
delegate void IntMethodInvoker(int x);
在该示例中,定义了一个委托IntMethodInvoker,并指定该委托的每个实例都可以包含一个方法的引用,该方法带有一个int参数,并返回void。
方法两个long,返回double
delegate double TwoLongsOp(long first,long second);
不带参,返回string
delegate string GetAString();
可以在定义类的任何地方定义委托,亦可用public protected private修饰
8.2.2使用委托
下面是int上调用ToString()方法的一种相当冗长的方式:
private delegate string GetAString();
static void Main(){
int x=40;
GetAString firstStringMethod=new GetAString(x.ToString);
Console.WriteLine("String is {0}",firstStringMethod());
//完全等价于Console.WriteLine("String is {0}",x.ToString());
}
实际上,给委托实例提供圆括号与调用委托类的Invoke()方法完全相同。
为了减少输入量,只是需要委托实例,就可以只传送地址的名称,这称为委托推断。
只要编译器可以把委托实例解析为特定的类型,这个C#特性就是有效的。
GetString firstStringMethod = new GetAString(x.ToString);
GetString firstStringMethod = x.ToString;
上面两个C#编译器创建的代码是一样的。
注:上面用的是x.ToString,而不是x.ToString(),ToString()返回的是不能赋予委托变量的字符串对象,只能把方法的地址赋予委托变量。
struct Currency{
public uint Dollars;
public ushort Cents;
public Currency(uint dollars,ushort cents){
this.Dollars=dollars;
this.Cents=cents;
}
public override string ToString(){
return string.Format("${0}.{1,2:00}",Dollars,Cents);
}
public static string GetCurrencyUnit(){
return "Dollars";
}
public static explicit operator Currency(float value){
checked{
uint dollars=(uint)value;
ushort cents=(ushort)((value-dollars)*100);
return new Currency(dollars,cents);
}
}
public static implicit operator float(Currency value){
return value.Dollars+(value.Cents/100.0f);
}
public static implicit operator Currency(uint value){
return new Currency(value,0);
}
public static implicit operator uint(Currency value){
return value.Dollars;
}
}
private delegate string GetAString();
static void Main(){
int x=40;
GetAString firstStringMehtod=x.ToString;
Console.WriteLine("String is {0}",firstStringMethod());
Currency balance=new Currency(34,50);
firstStringMethod=balance.ToString;
Console.WriteLine("String is {0}",firstStringMethod());
firstStringMethod=new GetString(Currency.GetCurrencyUnit);
Console.WriteLine("String is {0}",firstStringMethod());
}
8.2.3简单的委托示例
class MathOperations{
public static double MultiplyByTwo(double value){
return value*2;
}
public static double Square(double value){
return value*value;
}
}
下面调用:
using System;
namespace A{
delegate double DoubleOp(double x);
class Program{
static void Main(){
DoubleOp[] operations={
MathOperations.MultiplyByTwo,
MathOperations.Square
};
for(int i=0;i<operations.Length;i++){
Console.WriteLine("Using operation[{0}]",i);
ProcessAndDisplayNumber(operation[i],2.0);
ProcessAndDisplayNumber(operation[i],7.94);
ProcessAndDisplayNumber(operation[i],1.414);
}
}
static void ProcessAndDisplayNumber(DoubleOp action,double value){
double result=action(value);
Console.WriteLine("Value is {0},result of operation is {1}",value,result);
}
}
}
//注:太厉害了,我啊啊啊了!!!
(2014.12.17)
(伟大的人类仍在爬行中……)
第八章:委托、Lambda表达式和事件
8.1引用方法
委托是寻址方法的.NET版本。在C++中,指针是危险的。而委托是类型安全的类,它定义了返回类型和参数的类型,委托类不仅包含对方法的引用,也可以包含对多个方法的引用。
Lambda表达式与委托直接相关。当参数是委托类型时,就可以使用Lambda表达式实现委托引用的方法。
8.2委托
当要把方法传送给其他方法时,需要使用委托:
int i=int.Parse("99");
.NET Framework在语法上不允许使用这种直接方法。如果要传递方法,就必须把方法的细节封装在一种新类型的对象中,即委托。委托只是一种特殊类型的对象,其特殊之处在于,我们以前定义的所有对象都包含数据,而委托包含的只是一个或多个方法的地址
8.2.1声明委托
在C#中使用一个类时,分两个阶段。
首先,需要定义这个类,即告诉编译器这个类由什么字段和方法使用。
然后(除非只使用静态方法),实例化类的一个对象。
使用委托时,也需要经过这两个步骤。
首先必须定义要使用的委托,对于委托,定义它就是告诉编译器这种类型的委托表示哪种类型的方法。
然后必须创建该委托的一个或多个实例。
定义委托的语法:
delegate void IntMethodInvoker(int x);
在该示例中,定义了一个委托IntMethodInvoker,并指定该委托的每个实例都可以包含一个方法的引用,该方法带有一个int参数,并返回void。
方法两个long,返回double
delegate double TwoLongsOp(long first,long second);
不带参,返回string
delegate string GetAString();
可以在定义类的任何地方定义委托,亦可用public protected private修饰
8.2.2使用委托
下面是int上调用ToString()方法的一种相当冗长的方式:
private delegate string GetAString();
static void Main(){
int x=40;
GetAString firstStringMethod=new GetAString(x.ToString);
Console.WriteLine("String is {0}",firstStringMethod());
//完全等价于Console.WriteLine("String is {0}",x.ToString());
}
实际上,给委托实例提供圆括号与调用委托类的Invoke()方法完全相同。
为了减少输入量,只是需要委托实例,就可以只传送地址的名称,这称为委托推断。
只要编译器可以把委托实例解析为特定的类型,这个C#特性就是有效的。
GetString firstStringMethod = new GetAString(x.ToString);
GetString firstStringMethod = x.ToString;
上面两个C#编译器创建的代码是一样的。
注:上面用的是x.ToString,而不是x.ToString(),ToString()返回的是不能赋予委托变量的字符串对象,只能把方法的地址赋予委托变量。
struct Currency{
public uint Dollars;
public ushort Cents;
public Currency(uint dollars,ushort cents){
this.Dollars=dollars;
this.Cents=cents;
}
public override string ToString(){
return string.Format("${0}.{1,2:00}",Dollars,Cents);
}
public static string GetCurrencyUnit(){
return "Dollars";
}
public static explicit operator Currency(float value){
checked{
uint dollars=(uint)value;
ushort cents=(ushort)((value-dollars)*100);
return new Currency(dollars,cents);
}
}
public static implicit operator float(Currency value){
return value.Dollars+(value.Cents/100.0f);
}
public static implicit operator Currency(uint value){
return new Currency(value,0);
}
public static implicit operator uint(Currency value){
return value.Dollars;
}
}
private delegate string GetAString();
static void Main(){
int x=40;
GetAString firstStringMehtod=x.ToString;
Console.WriteLine("String is {0}",firstStringMethod());
Currency balance=new Currency(34,50);
firstStringMethod=balance.ToString;
Console.WriteLine("String is {0}",firstStringMethod());
firstStringMethod=new GetString(Currency.GetCurrencyUnit);
Console.WriteLine("String is {0}",firstStringMethod());
}
8.2.3简单的委托示例
class MathOperations{
public static double MultiplyByTwo(double value){
return value*2;
}
public static double Square(double value){
return value*value;
}
}
下面调用:
using System;
namespace A{
delegate double DoubleOp(double x);
class Program{
static void Main(){
DoubleOp[] operations={
MathOperations.MultiplyByTwo,
MathOperations.Square
};
for(int i=0;i<operations.Length;i++){
Console.WriteLine("Using operation[{0}]",i);
ProcessAndDisplayNumber(operation[i],2.0);
ProcessAndDisplayNumber(operation[i],7.94);
ProcessAndDisplayNumber(operation[i],1.414);
}
}
static void ProcessAndDisplayNumber(DoubleOp action,double value){
double result=action(value);
Console.WriteLine("Value is {0},result of operation is {1}",value,result);
}
}
}
//注:太厉害了,我啊啊啊了!!!
(2014.12.17)