c# 优化代码的一些规则——使用is或as和强制类型转换的区别[三]

前言

使用as和强制类型转换的时候的区别是否仅仅是代码形式上的区别。编程

答案是确定不是的。性能

正文

看两段代码:code

object o = Factory.GetObject();
Student student = o as Student;
if (student != null)
{
	//dosomething
}

对象

object o = Factory.GetObject();
Student student = o as Student;
try
{
	Student student = (Student)o;
	if (student != null)
	{
		//dosomething
	}
}
catch (InvalidCastException e)
{
	var str = e.Message;
}

问题来了,这二者有什么区别?blog

首先第二个里面有一个损失性能的地方,就是try{}catch{}。ci

那么能够确定一点就是在程序健壮性相同的状况下,使用as最好。get

问题又出现了,那么何时不能用as呢?或者as 和 强制类型转换之间差异是什么呢?it

as 转换的局限性在于,他只会作简单的装箱和拆箱工做,而不会去作一些类型转换。io

也就是说,若是待转换的对象既不属于目标对象,也不属于派生出来的类型那么是不能转换的。编译

这里就有人奇怪了,若是二者都不属于那么转换失败正常啊。

怎么说呢,请考虑下面两种状况:

1.数值之间转换,好比int转long之类的。

2.本身实现转换,如:implicit

这二者as搞不定的。

好比说:

有一个child 类,想转学生类。

这样写:

public class Child
{
	public static implicit operator Student(Child child)
	{
		return new Student();
	}
}

而后我来这样写:

object o = Factory.GetObject();
Student student = o as Student;
if (student != null)
{
	//dosomething
}

GetObject为:

public static implicit operator Student(Child child)
{
	return new Student();
}

这样写是不成功的。

图我贴出来了。

那么我这样写,是否能成功呢?

object o = Factory.GetObject();
try
{
	Student student = (Student)o;
	if (student != null)
	{
		//dosomething
	}
}
catch (InvalidCastException e)
{
	var str = e.Message;
}

遗憾的是,这样写也是失败的。

那么为何失败呢?

C# 有一个编译期和一个运行期。

而强制转换发送在编译期。

也就是说它读取的是object能不能转换为Student,而不是在运行期的Child。

好的,那么你能够这样。

object o = Factory.GetObject();
var c = o as Child;
try
{
	Student student = (Student)c;
	if (student != null)
	{
		//dosomething
	}
}
catch (InvalidCastException e)
{
	var str = e.Message;
}

这样是对的,可是对于编程学来讲,谁会去这样写呢,在不少时候咱们应该尽可能避免装箱和拆箱。

在此总结一下,那就是as 运行在运行期,而cast 在编译期。

好的,as 完了后,看下is吧。

is 是遵照多态的,多态很好理解哈。

因此is 不是==的意思,而是是不是本身或者子类的意思。

若是你想要去获得具体的类型判断,那么请使用getType更为合适。

总结

使用as或者 强制类型转换没有定性的要求,看具体的方案,而后呢当可使用as的时候尽可能使用as,毕竟能够避免try catch这种消耗性能的东西。

相关文章
相关标签/搜索