C#委托好处知多少

1.性能

性能是泛型的一个主要优点。

直接上例子,通过实例可以让我们很好的理解这一点。

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start(); //开始监视

//-----代码片段1------------------Start
ArrayList al = new ArrayList();
for (int i = 1; i <= 10000000; i++)
{
     al.Add(i);
}
foreach (int i in al)
{
     //do what you want
     int j = i + 1;
}
//-----代码片段1------------------End

stopwatch.Stop(); //停止监视
TimeSpan timespan = stopwatch.Elapsed; //获取代码运行时间
Console.WriteLine("代码片段1执行时间为:" + timespan.ToString());

Stopwatch stopwatch1 = new Stopwatch();
stopwatch1.Start(); //开始监视

//-----代码片段2------------------start
List<int> il = new List<int>();
for (int i = 1; i <= 10000000; i++)
{
     il.Add(i);
}
foreach (int i in il)
{
     //do what you want
     int j = i + 1;
}
//-----代码片段2------------------end

stopwatch1.Stop(); //停止监视
TimeSpan timespan1 = stopwatch1.Elapsed; //获取代码运行时间
Console.WriteLine("代码片段2执行时间为:" + timespan1.ToString());

代码运行结果为:

很显然,代码片段1的运行时间远远大于代码片段的运行时间。

下面将详细地说明一下代码片段1及代码片断2都干了些什么,以及是什么造成了两段代码运行时间的巨大差距。

首先,你应该能看出,代码片段1与代码片段2的功能完全等价,都是将110000000之间的整数循环添加进集合(ArrayList或List<T>),再从集合中循环取出这10000000个整数,做你想做的处理(想做就做呗,呵呵)。

既然功能一样,那么性能为什么会有如此之大的区别呢。

因为代码片段1中,ArrayList存储对象时,Add()方法被定义为接受一个对象(object)作为参数(见图* ArrayList Add()方法签名),所以使用Add()方法接受一个整型数据时,需要进行装箱操作。在读取ArrayList中的元素时,要进行拆箱,把对象转换成整型类型。

图* ArrayList Add()方法签名

可见,装箱与拆箱的实现并不难,但是性能损失较大。

当循环迭代次数很多时,性能损耗尤其明显。对于这一点,我们可以做个简单的实验,将实例的循环次数改为1000,得到以下结果:

结果显示:这种情况下,代码片段1的执行时间约为代码片段2执行时间的两倍。而循环次数为10000000时,代码片段1的执行时间约为代码片段2执行时间的四倍。

最后,将循环次数设置为1,此时运行结果为:

这种情况下,代码片段1的执行时间仍约为代码片段2执行时间的两倍(其实是1.9倍,倍数是减少了点,不过跟循环1000次区别不大)。

对于这一点就不赘述了,只要有这种印象就行了。

代码片段2中,List<T>类不使用对象,而是在使用时定义类型。在本实例中,泛型类型被定义为int,所以代码片段2中相关操作均会使用int类型(见图** List<int>类 Add()方法签名),不管是循环添加数据还是循环读取数据,都将使用int类型,所以不存在装箱与拆箱操作。

图** List<int>类 Add()方法签名 

到这里,我们已经可以很好的理解:性能是泛型的主要优点。

2.类型安全

聊完了性能,来聊聊泛型的另一个优点,类型安全。

在介绍类型安全时,我们还是会使用ArrayList与List<T>作为演示对象。

//-----代码片段3------------------Start
ArrayList al = new ArrayList();
al.Add(1);
//下面的代码编译没问题,但是运行时会报错
al.Add("tiana0");
foreach (int i in al)
{
    //do what you want
}
//-----代码片段3------------------End

//-----代码片段4------------------start
List<int> il = new List<int>();
il.Add(1);
//下面的代码编译器会提示与“System.Collections.Generic.List<int>.Add(int)”最匹配的重载方法具有一些无效参数
//编译就无法通过
il.Add("tiana0");
foreach (int i in il)
{
    //do what you want
}
//-----代码片段4------------------end

代码片段3,能够正常编译,但是执行时会报错,错误信息如下:

提示“制定的转换无效”。

分析代码,我们很容易定位异常代码位置:foreach (int i in al)因为在前面我们给ArrayList添加了字符串元素“tiana0”,而该元素是不可能转换成整型数据的,导致程序无法执行而出现一个运行异常。

对于代码片段4,错误在编译时就被及时的发现了。因为有了List<T>的定义,就只能把整型数据添加到集合中,将字符串添加到集合时会导致编译错误,提示与“System.Collections.Generic.List<int>.Add(int)”最匹配的重载方法具有一些无效参数

所以,使用泛型时,编译器可以执行更多地检查,确保类型安全。

而在使用ArrayList时,你可以向集合中添加任何元素,可以是整型数据,可以是字符串,还可以是自定义类型数据,无法确保类型安全。

到这里,我们得出结论:类型安全是泛型的另一特点。

3.二进制代码重用

这个较好理解,泛型类型可以在一种语言中定义,在另一种.Net语言中使用。

就总结到这里了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C# 委托(Delegate)是一种类型,它可以用于封装一个或多个方法,使其可以像其他对象一样传递、存储和调用。委托在事件处理、多线程等方面有着广泛的应用。 C# 委托的声明方式与方法类似,可以带有参数和返回值类型,例如: ```csharp public delegate int Calculate(int a, int b); ``` 上面的代码声明了一个名为 `Calculate` 的委托类型,它包含两个 `int` 类型的参数并返回一个 `int` 类型的值。接下来可以使用这个委托类型来封装一个或多个方法委托使用步骤如下: 1. 声明委托类型 ```csharp public delegate void MyDelegate(string message); ``` 2. 定义委托变量 ```csharp MyDelegate myDelegate; ``` 3. 实例化委托变量 ```csharp myDelegate = new MyDelegate(MethodA); ``` 4. 调用委托 ```csharp myDelegate("Hello"); ``` 完整的示例代码如下: ```csharp using System; namespace DelegateDemo { public delegate void MyDelegate(string message); class Program { static void Main(string[] args) { MyDelegate myDelegate; myDelegate = new MyDelegate(MethodA); myDelegate += new MyDelegate(MethodB); myDelegate("Hello"); } static void MethodA(string message) { Console.WriteLine("MethodA: " + message); } static void MethodB(string message) { Console.WriteLine("MethodB: " + message); } } } ``` 上面的代码定义了一个名为 `MyDelegate` 的委托类型,包含一个 `string` 类型的参数并返回一个 `void` 类型的值。在 `Main` 方法中,首先将 `myDelegate` 委托变量实例化为 `MethodA` 方法,然后再将其实例化为 `MethodB` 方法。最终调用 `myDelegate` 委托变量时,将会依次调用 `MethodA` 和 `MethodB` 方法。 除了以上示例中的简单委托,还有多播委托、泛型委托、匿名委托等更加高级的委托用法,可以根据具体需求选择使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值