C#泛型与委托

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值