今天在看一篇有关数据类型的文章的时候,无心间看到了两个关键词,“隐式转换”与“显示转换”,而后忽然想起了当初开始学编程的时候,也老是在代码编译的时候遇到这样的问题。程序员
那么,今天恰好有空来总结一下这二者之间到底存在着怎么样的关系。编程
先来看看以下几个问题:spa
我先定义了一个变量:code
string a = 5;
这个只要是有点常识的人均可以一眼看出问题所在。blog
而后在看看以下代码:开发
double d1 = 5; float f1 = d1;
按咱们所预料的那样,如今咱们试着尝试编译一下,而后经过控制台输出f1。get
结果尽然编译的时候都没法经过,报出以下异常:编译器
而后再看看以下代码:string
float f1 = 5; double d1 = f1; Console.WriteLine(f1);
再编译,并运行。结果是编译成功,并完美运行:pm2
面对第一个编译时出现的转换,咱们稍做修改,修改以下:
double d1 = 5; float f1 = (float)d1;
而后编译,运行,结果是完美运行:
看到如此场景,有人会以为好奇怪。
这里就关系到了咱们以前所说的隐式转换与显示转换。
隐式转化:即数据的类型的转换由编译器自动进行的,不须要人工干预的数据转换。
显示转换:与隐式转换相反的数据类型的转换,即须要人为强制干预的数据转换。
而上述三段代码编译和运行,第1、第二段代码的转换就属于隐式转换,而第三段代码则是使用了显示转换后才正确的执行。
那什么状况下两个数据数据类型之间只须要隐式转换就能够实现转换,而什么状况下却有须要进行强制转换。
下面先来看一张表:
看完这张表,咱们会发现float类型表示的是32位的浮点值,而double类型表示的是64位的浮点值。恰好float转换成double则隐式转换就可实现,而double转换到float则须要强制转换,就是显示转换。
而double类型的值范围大于float类型的值范围,因此float转double能够隐式转换,double转float却须要显示转换。
由此得出以下结论:
当被转换类型的值范围小于目标类型的值范围时能够执行隐式转换,不然隐式转换是编译器会报异常。也就是说大存储容量的数据类型能够容纳小存储容量的数据类型,反之则不行。
那么隐式转换要具有的条件是:
1. 被转换类型的值范围必须包含目标类型的值范围;
2. 被转换类型的值必须与目标类型兼容。
而显示转换要被的条件则是:
1. 被转换类型的值要在目标类型的值范围之类,若是超出目标类型的最大或最小值,则编译器会抛出异常,转换不成功。
2. 被转换类型的值一样必须与目标类型互相兼容。
一样,隐式转换与显示转换在引用类型中一样适用。下面定义了两个类。
/// <summary> /// 人类 /// </summary> public class Persion { public int Id { get; set; } public int Sex { get; set; } public int Age { get; set; } public int Height { get; set; } } /// <summary> /// 程序类 /// </summary> public class Programmer : Persion { public string Job { get; set; } public string Postion { get; set; } }
以上两个类的字段随意定义,可能不合理,在此只是说明其转换的问题。
而后作以下初始化和转换:
Programmer pm1 = new Programmer() { Id = 1, Age = 25, Height = 168, Job = "程序员", Sex = 1 }; Persion p1 = pm1;
编译之后,显示编译经过:
再看另外一段代码:
Persion p2 = new Persion() { Id = 1, Age = 20, Sex = 1, Height = 180 }; Programmer pm2 = p2;
在编译,结果显示异常:
所以,在引用类型中,好比类与类之间的转换,一样都须要遵循隐式转换与显示转换的原理和规则。
固然,有转换就必有数据损失,这是没法避免的,只能说开发人员在使用这些数据类型转换的时候要可以明白可能会形成什么样的损失,以及以怎样最合理的方式使用它们,才能在使用过程当中形成没必要要的损失。