浅析“强制类型转换”带来的性能分析及其解决方法
一个“强制转换”的例子引发的思考:
在C Sharp语言中,进行强制类型转换的另外一种方式是is操作符。is操作符检测一个对象是否兼容于指定的类型,并返回一个Bool值。请注意:我在MSDN中查过资料,说明is操作符永远不会抛出异常,从而增加了代码执行的安全性。如下面例子:
输入结果是:1,因为f对象输入Fruit类,如果直接调用Console.WriteLine(f.i)会出现编译错误,为了能够调用Apple类里面的pubilc型 int i,需要强制类型转换,这里if语句中的条件起一个判断作用,道理很简单,这里我理解is相当于"包含之意",因为Apple:Fruit,所以需要一个转换过程,Apple a=(Apple)f;然后在输出。写到这里,问题来了,细心研究的朋友会发现CLR在执行if语句的时候,会两次类型检测,从安全性来说,没有问题,但是从性能来说,就有问题了,如果这种情况多次发生,或者说多次转换,性能问题......有没有解决的办法了?答案是有的。经过我仔细查阅MSDN上面的资料,我们可以用as操作符解决。代码如下:
1
using System;
2
class Fruit
3
{
4
//省略
5
}
6
class Apple:Fruit
7
{
8
public int i=1;
9
}
10
class Conversions
11
{
12
static void Main()
13
{
14
Fruit f =new Apple();//CLR允许将一个对象实例强制转换为它的基类型,此转换是隐式转换。
15
//Apple a=new Fruit();
16
// Type t=f.GetType();
17
//Console.WriteLine(t.FullName); 查看所属那个class;
18
Console.WriteLine(f.i);//调用出错
19
Apple a=(Apple)f;//强制类型转换
20
Console.WriteLine(a.i);
21
//Console.WriteLine(((Apple)f).i);
22
}
23
}
24![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
4
![](/Images/OutliningIndicators/InBlock.gif)
5
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
8
![](/Images/OutliningIndicators/InBlock.gif)
9
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
10
![](/Images/OutliningIndicators/None.gif)
11
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/InBlock.gif)
21
![](/Images/OutliningIndicators/InBlock.gif)
22
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
23
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
24
![](/Images/OutliningIndicators/None.gif)
在C Sharp语言中,进行强制类型转换的另外一种方式是is操作符。is操作符检测一个对象是否兼容于指定的类型,并返回一个Bool值。请注意:我在MSDN中查过资料,说明is操作符永远不会抛出异常,从而增加了代码执行的安全性。如下面例子:
1
using System;
2
class Fruit
3
{
4
5
}
6
class Apple:Fruit
7
{
8
public int i=1;
9
}
10
class Conversions
11
{
12
static void Main()
13
{
14
Fruit f=new Fruit();
15
Apple a=new Apple();
16
Console.WriteLine(f is Fruit);//返回true
17
Console.WriteLine(f is Apple);//返回false
18
Console.WriteLine(a is Fruit);//返回true
19
Console.WriteLine(a is Apple);//返回true
20
}
21
}
22
这个很简单,下面改写Main()里面的代码,慢慢引入有意思的问题:
23
{
24
Fruit f=new Apple();
25
if (f is Apple)
26
{
27
Apple a=(Apple)f;
28
Console.WriteLine(a.i);
29
}
30
}
31![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
4
![](/Images/OutliningIndicators/InBlock.gif)
5
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
6
![](/Images/OutliningIndicators/None.gif)
7
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
8
![](/Images/OutliningIndicators/InBlock.gif)
9
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
10
![](/Images/OutliningIndicators/None.gif)
11
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
12
![](/Images/OutliningIndicators/InBlock.gif)
13
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
14
![](/Images/OutliningIndicators/InBlock.gif)
15
![](/Images/OutliningIndicators/InBlock.gif)
16
![](/Images/OutliningIndicators/InBlock.gif)
17
![](/Images/OutliningIndicators/InBlock.gif)
18
![](/Images/OutliningIndicators/InBlock.gif)
19
![](/Images/OutliningIndicators/InBlock.gif)
20
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
21
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
22
![](/Images/OutliningIndicators/None.gif)
23
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
24
![](/Images/OutliningIndicators/InBlock.gif)
25
![](/Images/OutliningIndicators/InBlock.gif)
26
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
27
![](/Images/OutliningIndicators/InBlock.gif)
28
![](/Images/OutliningIndicators/InBlock.gif)
29
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
30
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
31
![](/Images/OutliningIndicators/None.gif)
输入结果是:1,因为f对象输入Fruit类,如果直接调用Console.WriteLine(f.i)会出现编译错误,为了能够调用Apple类里面的pubilc型 int i,需要强制类型转换,这里if语句中的条件起一个判断作用,道理很简单,这里我理解is相当于"包含之意",因为Apple:Fruit,所以需要一个转换过程,Apple a=(Apple)f;然后在输出。写到这里,问题来了,细心研究的朋友会发现CLR在执行if语句的时候,会两次类型检测,从安全性来说,没有问题,但是从性能来说,就有问题了,如果这种情况多次发生,或者说多次转换,性能问题......有没有解决的办法了?答案是有的。经过我仔细查阅MSDN上面的资料,我们可以用as操作符解决。代码如下:
1
Fruit f=new Apple();
2
Apple a=f as Apple;
3
if(a!=null)
4
{
5
Console.WriteLine(a.i);
6
}
7![](/Images/OutliningIndicators/None.gif)
说明:as操作符跟is一样都是返回一个Bool值,一个对象得引用。区别在于as操作符只进行一次对象的引用,并且速度比is操作符快很多,所以性能大大提高。
![](/Images/OutliningIndicators/None.gif)
2
![](/Images/OutliningIndicators/None.gif)
3
![](/Images/OutliningIndicators/None.gif)
4
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
5
![](/Images/OutliningIndicators/InBlock.gif)
6
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
7
![](/Images/OutliningIndicators/None.gif)
posted on 2008-03-24 11:46 CodeShark 阅读(2938) 评论(6) 编辑 收藏 举报