一直都会有意无意地使用到类型的转换。int a = 5.23;string s = "abc" + intValue;也许在看书的时候你也会看到int a = (int)5.23;string s = "abc"+(string)intValue; 这样的写法。我想也应该会有很多人像我一样想过这样的显式真是画蛇添足了,当然我们可以选择简洁的隐式,也可以选择看起来更专业一点的显式。那么就仅此而以吗,对的这里的效果确实如此,至少是表面上看起来一样了。
我也就这样理解了,直到我看到一个显式的转换
namespace test4
{
public class Car
{
private int speed = 10;
public Car() { }
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public class ACar : Car
{
public int speed = 20;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
class Program
{
static void Main(string[] args)
{
Car a = new ACar();
ACar b = (ACar)a;
b.speed = 30;
}
}
}
很啰嗦的一堆不是么,我们只要看这个句就够了
Car a = new ACar();
ACar b = (ACar)a;
b.speed = 30;
不知道你是如何来理解它的,不过告诉你它是可以正确运行的,或者你根本就没看到有什么不对的,那么让我们分析一下。
ACar继承于Car,ACar也是一种Car,则ACar可以拥有Car的一切公有功能,还有除此之外的一些自己的功能,如果是这样ACar a = new Car();一个Car对象当然只能运行Car的方法,如果给a一个ACar特有的消息,那就是一个子虚乌有的功能了,我们说这是一种不安全的赋值,在编译器上是不可通过的。相反的Car a = new ACar()就是安全的。
又正如前面所说的ACar b = (ACar)a;把一个Car的对象赋值给ACar变量,那么它也算得是不安全的了,那又是否可以通过呢。这就是显式也叫强制类型转换的原因了,如果这样,ACar b = a;那么不用运行了,编译的时候就会返给你错误的(编译器毕竟还不能如人一样聪明到可以分析如此的复杂)。
我们这里也就是把一个ACar的对象赋值给一个Car指针,再被赋值给ACar指针,最后就是ACar b = new ACar();
那么这么说来不是显式的功能更强大么,为何又要没有显式的必要。我们应该都会知道一个道理--任何的好处都是要以牺牲别一部分为前提的,这里牺牲的就是安全性。如果在你不知道或者不能完全控制指针之间的确切关系的话,那就是一种很严重的潜在危险了。当然显式转换的错误在程序runtime里也会有检测,但我想那并不是我们程序员想要的。
所以我们有一个原则,那就是在类型中尽量使用隐式转换,在实在有必要的地方才使用显卡转换。我相信就算是int a = (int)2.35在runtime里也会被加入了动态检测的列队,而这一切都是可以在编译时就可以完成的。
我也就这样理解了,直到我看到一个显式的转换
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
Car a = new ACar();
ACar b = (ACar)a;
b.speed = 30;
不知道你是如何来理解它的,不过告诉你它是可以正确运行的,或者你根本就没看到有什么不对的,那么让我们分析一下。
ACar继承于Car,ACar也是一种Car,则ACar可以拥有Car的一切公有功能,还有除此之外的一些自己的功能,如果是这样ACar a = new Car();一个Car对象当然只能运行Car的方法,如果给a一个ACar特有的消息,那就是一个子虚乌有的功能了,我们说这是一种不安全的赋值,在编译器上是不可通过的。相反的Car a = new ACar()就是安全的。
又正如前面所说的ACar b = (ACar)a;把一个Car的对象赋值给ACar变量,那么它也算得是不安全的了,那又是否可以通过呢。这就是显式也叫强制类型转换的原因了,如果这样,ACar b = a;那么不用运行了,编译的时候就会返给你错误的(编译器毕竟还不能如人一样聪明到可以分析如此的复杂)。
我们这里也就是把一个ACar的对象赋值给一个Car指针,再被赋值给ACar指针,最后就是ACar b = new ACar();
那么这么说来不是显式的功能更强大么,为何又要没有显式的必要。我们应该都会知道一个道理--任何的好处都是要以牺牲别一部分为前提的,这里牺牲的就是安全性。如果在你不知道或者不能完全控制指针之间的确切关系的话,那就是一种很严重的潜在危险了。当然显式转换的错误在程序runtime里也会有检测,但我想那并不是我们程序员想要的。
所以我们有一个原则,那就是在类型中尽量使用隐式转换,在实在有必要的地方才使用显卡转换。我相信就算是int a = (int)2.35在runtime里也会被加入了动态检测的列队,而这一切都是可以在编译时就可以完成的。