您的位置:首页 > 编程语言 > C#

C#泛型与委托

2015-10-28 17:34 411 查看

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: