C#泛型与委托

来源:互联网 发布:软件测试理论基础知识 编辑:程序博客网 时间:2024/05/17 23:31

C#泛型与委托


时间:2015.10.28

泛型

定义

  • T
    • 可以作为各种类型进行使用,方便编程
  • 在函数中的定义

    private T MyFunc<T>(T a){    object tmp = a;    if (a is int)        return (T)((object)(Convert.ToInt32(tmp) * 3));    else if (a is double)        return (T)((object)(Convert.ToDouble(tmp) * 0.5));    else        return a;}
  • 如上,在泛型不能直接和其他类型的数据进行操作,需要先将泛型转化为转化为另外一个操作数的类型,之后转化为object,再强制转化为T(具体的类型不能直接转化为泛型)。

委托

定义

  • 直接定义如下即可
    • public delegate T Calculator(T x);
  • 对委托的函数定义如下:

    private T MyFunc<T>(T a){    if (a is int)        return (T)((object)(Convert.ToInt32(a) * 3));    else if (a is double)        return (T)((object)(Convert.ToDouble(a) * 0.5));    else        return a;}
  • 只要和委托的参数类型相同,都可以作为委托的“实例化”
  • 具体的调用方法如下:

    int[] a = new int[] { 1, 3, 5 };MyUtility.Calculate<int>(a,MyFunc);

作用

  • 实现插件式编程:可以执行任意一个参数形式相同的函数的方法

多播委托

  • 一个委托可以指向不止一个方法,即可以实现多个方法,见下面的实例
  • 首先定义一个委托

    public delegate void ProgressReporter(int percent);

  • 按键响应事件如下:

    private void button4_Click(object sender, RoutedEventArgs e){    ProgressReporter p = null;    p += WriteToConsole;    p += WriteToFile;    MyUtility.MyMatch(p);    Console.WriteLine("finished");}static void WriteToConsole(int per){    Console.WriteLine(per+"%");}static void WriteToFile(int per){    System.IO.File.AppendAllText("E:/test.txt", per + "%\r\n");}
  • MyMatch定义如下:

    public static void MyMatch(ProgressReporter p){    if (p != null)    {        for (int i = 0; i <= 10; i++)        {            p(i * 10);            Thread.Sleep(100);        }    }}

Func和Action委托

  • 相同点:都是新的委托,接受多个参数,都是为了简化代码(不使用delegate),Func 和 Action 委托,除了ref参数和out参数,基本上能适用于任何泛型委托的场景
  • 不同点:Func有返回值,Action无返回值
  • Action委托示例如下:

    //使用了兼容的参数private void button5_Click(object sender, RoutedEventArgs e){    Action<object> action = null;    action = MyAction;    action(3);}private void MyAction(object a){    Console.WriteLine(a);}

    不用再用delegate定义委托,非常方便。

委托的比较

  • 对于具体相同的目标方法的委托被视为相等;
  • 对于多播委托,相同的方法有对应的相同的顺序,则也被视为相等

事件

角色

  • 广播者:包括一个委托字段,通过调用委托发出广播
  • 订阅者:通过+=和-=的形式开始或者停止订阅

定义

  • 直接在声明委托时加event关键字即可,如下

    public event PriceChangedHandler PriceChanged;

实例分析

  • 以下是价格改变时会调用价格改变函数

MyMobile的定义

public class MyMobile{    private int price = 0;    public PriceChangedEventHandler priceChanged;    public MyMobile(int p)    {        price = p;    }    public int Price    {        get        {            return price;        }        set        {            int oldPrice = price;            this.price = value;            priceChanged(oldPrice,price);        }    }}

按键响应以及对应的价格改变函数

    private void button1_Click(object sender, RoutedEventArgs e)    {        MyMobile m = new MyMobile(1000);        m.priceChanged += changedP;        m.Price = 500;    }    private void changedP(int o, int p)    {        if (o != p)        {            Console.WriteLine("ori: "+o+" , now: "+p);        }    }
1 0