C#之隐式与显示类型转换

摘要:
今天,在阅读一篇关于数据类型的文章时,我无意中看到了两个关键词,“隐式转换”和“显示转换”。然后我突然想起,当我开始学习编程时,我在编译代码时总是遇到这个问题。double类型的值范围大于float类型的值,因此从float到double的转换可以是隐式的,而从double到float的转换需要显示。

今天在看一篇有关数据类型的文章的时候,无意间看到了两个关键词,“隐式转换”与“显示转换”,然后突然想起了当初开始学编程的时候,也总是在代码编译的时候遇到这样的问题。

那么,今天刚好有空来总结一下这两者之间到底存在着怎么样的关系。

先来看看如下几个问题:

我先定义了一个变量:

string a = 5;

这个只要是有点常识的人都可以一眼看出问题所在。

然后在看看如下代码:

double d1 = 5;
float f1 = d1;

按我们所预料的那样,现在我们试着尝试编译一下,然后通过控制台输出f1。

结果尽然编译的时候都无法通过,报出如下异常:

C#之隐式与显示类型转换第1张

然后再看看如下代码:

float f1 = 5;
double d1 = f1;
Console.WriteLine(f1);

再编译,并运行。结果是编译成功,并完美运行:

C#之隐式与显示类型转换第2张

C#之隐式与显示类型转换第3张

面对第一个编译时出现的转换,我们稍作修改,修改如下:

double d1 = 5;
float f1 = (float)d1;

然后编译,运行,结果是完美运行:

C#之隐式与显示类型转换第4张

看到如此场景,有人会觉得好奇怪。 

这里就关系到了我们之前所说的隐式转换与显示转换。


隐式转化:即数据的类型的转换由编译器自动进行的,不需要人工干预的数据转换。

显示转换:与隐式转换相反的数据类型的转换,即需要人为强制干预的数据转换。

而上述三段代码编译和运行,第一、第二段代码的转换就属于隐式转换,而第三段代码则是使用了显示转换后才正确的执行。

那什么情况下两个数据数据类型之间只需要隐式转换就可以实现转换,而什么情况下却有需要进行强制转换。

下面先来看一张表:

C#之隐式与显示类型转换第5张

 看完这张表,我们会发现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;

编译以后,显示编译通过:

C#之隐式与显示类型转换第6张

再看另一段代码:

            Persion p2 = new Persion() { Id = 1, Age = 20, Sex = 1, Height = 180 };
            Programmer pm2 = p2;

在编译,结果显示异常:

C#之隐式与显示类型转换第7张

 因此,在引用类型中,比如类与类之间的转换,同样都需要遵循隐式转换与显示转换的原理和规则。

当然,有转换就必有数据损失,这是无法避免的,只能说开发人员在使用这些数据类型转换的时候要能够明白可能会造成什么样的损失,以及以怎样最合理的方式使用它们,才能在使用过程中造成不必要的损失。

免责声明:文章转载自《C#之隐式与显示类型转换》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C# 的Color 颜色转换Delphi Byte数组与Int String之间的相互转换下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

VC6.0设定UNICODE编译环境

VC++ 6.0支持Unicode编程,但默认的是ANSI,所以开发人员只需要稍微改变一下编写代码的习惯便可以轻松编写支持UNICODE的应用程序。 1. 安装完成后:需要把VC98\MFC\LIB下的MFC42U*.*手动拷贝到对应的安装目录下2. 为工程添加UNICODE和_UNICODE预处理选项:打开[工程]->[设置…]对话框,在C/C++...

VCS学习(1)

一:如何执行(编译执行)   1:编译链接生成二进制可执行文件   $vcs source_file[compile_time_options],  例如 vcs +v2k filename.v -debug_all   (+2k指2001版本)     compile_time_options 可选项   A:基本可选项          -Mupdat...

关于编译Qt以及驱动的一点总结吧 Rollen Holt 博客园

关于编译Qt以及驱动的一点总结吧 - Rollen Holt - 博客园 关于编译Qt以及驱动的一点总结吧 通过这几次的折腾,对编译Qt算是有一点的心得吧: 首先我们编译QT的时候需要面对的是下载源代码,一般情况下我们建议下载qt-everywhere-opensource-src-4.8.2.zip这种形式的源代码。这样编译起来的问题也就很少了。当然...

从0开始编译安卓 9.0

手机是Google Pixel XL 编译环境的准备 google 9月更新了地址 https://source.android.com/setup/build/initializinghttps://source.android.com/setup/build/building ubuntu 16.0.4 x64 需要安装的软件包 看上面 的网址 经过测...

【问题解决记录】无法识别的标志“-sdlMode”,在“p2”中

本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/这是本人第一次使用MarkDown编辑器,试试看效果—w—,下面是正文: ## 一、报错原因 昨天用SIMD指令编写了几个矩阵计算函数,想要替换掉DX的函数达到优化性能的目的。 因为公司项目使用的编译器是VS2008,而VS2013编译出来的SI...

php性能调优

第一章  针对系统调用过多的优化 我这次的优化针对syscall调用过多的问题,所以使用strace跟踪apache进行分析。 1.  apache2ctl -X & 使用-X(debug)参数启动httpd进程,这个时候只启动1个httpd进程 2. ps -ef | grep httpd 找到需要strace的pid 3. strace -p...