《C#高级教程》学习笔记10

来源:互联网 发布:行业网站源码 编辑:程序博客网 时间:2024/05/03 08:25
第十五天
(伟大的人类仍在爬行中……)

第八章:委托、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)
0 0
原创粉丝点击