用户定义的数据类型转换

C#同意定义自己的 数据类型,这意味着须要某些 工具支持在自己的数据类型间进行数据转换.方法是把数据类型转换定义为相关类的一个成员运算符,数据类型转换必须声明为隐式或者显式,以说明怎么使用它.

C#同意用户进行两种定义的数据类型转换,显式和隐式,显式要求在代码中显式的标记转换,其方法是在原括号里写入目标数据类型.

对于提前定义的数据类型,当数据类型转换时可能失败或者数据丢失,须要显示转换:

1.把int数值转换成short时,由于short可能不够大,不能包括转换的数值.

2.把全部符号的数据转换为无符号的数据,假设有符号的变量包括一个负值,会得到不对的结果.

3.把浮点数转换为整数数据类型时,数字的小数部分会丢失.

此时应在代码中进行显示数据类型转换,告诉编译器你知道这会有丢失数据的危急,因此编写代码时把这些可能考虑在内.

注意:假设源数据值使数据转换失败,或者可能会抛出异常,就应把数据类型转换定义为显式.

定义数据类型转换的语法有点类似于运算符重载.

比如:隐式类型转换的代码:

public static inplicit operator float(Current current)

{}

和运算符重载同样,数据类型转换必须声明为public和static.

注意:

当数据类型转换声明为隐式时,编译器能够显式或隐式的调用数据类型转换.

当数据类型转换声明为显式的,编译器仅仅能显式的调用类型转换.

案例:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace 类型转换

{

class Program

{

static void Main(string[] args)

{

try

{

Current balance = new Current(50, 35);

Console.WriteLine(balance);

Console.WriteLine("balance using tostring() : + " + balance.ToString());

//隐式类型转换

float balance2 = balance;

Console.WriteLine("After converting to float : " + balance2);

//显示类型转换

balance = (Current)balance2;

Console.WriteLine("After converting to Current : " + balance);

float t = 45.63f;

Current c = (Current)t;

Console.WriteLine(c.ToString());

checked

{

balance = (Current)(-50.5);

Console.WriteLine("result is : " + balance.ToString());

}

}

catch (Exception)

{

Console.WriteLine("错误");

}

Console.ReadKey();

}

}

struct Current

{

public uint Dollars;

public ushort Cents;

//构造函数

public Current(uint dollars, ushort cents)

{

this.Dollars = dollars;

this.Cents = cents;

}

//重写ToString()方法

public override string ToString()

{

return string.Format("{0}.{1,-2:00}", this.Dollars, this.Cents);

}

//隐式类型转换

public static implicit operator float(Current value)

{

return value.Dollars + (value.Cents / 100.0f);

}

//显示类型转换

public static explicit operator Current(float f)

{

uint dollars = (uint)f;

ushort cents = (ushort)((f - dollars) * 100);

return new Current(dollars, cents);

}

}

}

将设计两个问题:

1.从float转换为Current得到错误的结果50.34,而不是50.35,----圆整造成的,发生截断问题.

答:假设float值转换为uint值,计算机就会截断多余的数字,而不是去圆整它.计算机数据是通过 二进制存储的,而不是十进制,小数部分0.35不能以二进制形式存储.由于舍弃一部分,故实际转换成的数据要小于0.35,即能够用二进制形式存储的值,然后数字乘以100,得到小于35的数字34,有时候这样的阶段是非常危急的,避免这样的错误的方式时确保在数字转换过程中运行智能圆整操作.

Microsoft编写了一个类System.Convert来完毕该任务.System.Convert包括大量的静态方法来运行各种数字转换,我们要使用的是Convert.ToUint16().注意,在使用System.Convert方法会产生额外的性能损耗,所以仅仅有在须要的时候才使用.

注意:System.Convert方法还运行他们自己的溢出检查,所以

Convert.ToUint16((f-dollars)*100);

这种代码能够不放在checked里面.

2.在试图转换超出范围的值时,没有发生异常.主要是由于:发生溢出的位置根本不在Main例程中--这是在转换运算符的代码中发生的,该代码在Main()方法中调用,该方法没有标记为checked,其解决方法:

代码:

public static explicit operator Current(float f)

{

checked

{

uint dollars = (uint)f;

ushort cents = Convert.ToUInt16((f - dollars) * 100);

return new Current(dollars, cents);

}

}

explicit和implicit属于转换运算符,乳痈这两者能够让我们自己定义的类型支持相互交换

explicit表示显示转换,从A->B必须进行强制类型转换:B=(B)A

implicit表示隐式转换,如从B->A仅仅须要直接复制A=B

隐式转换能够让我们的代码看上去更美丽,更简洁移动,所以最好多使用implicit运算符.只是,假设对象本身在转换时会损失一些信息(如精度),那么我们仅仅能使用explicit运算符,以便在编译期就能警告客户调用.

C#高级编程四十一天----用户定义的数据类型转换的更多相关文章

  1. C#编程(四十一)----------用户定义的数据类型转换

    用户定义的数据类型转换 C#允许定义自己的 数据类型,这意味着需要某些 工具支持在自己的数据类型间进行数据转换.方法是把数据类型转换定义为相关类的一个成员运算符,数据类型转换必须声明为隐式或者显式,以 ...

  2. [.net 面向对象编程基础] (4) 基础中的基础——数据类型转换

    [.net面向对象编程基础] (4)基础中的基础——数据类型转换 1.为什么要进行数据转换? 首先,为什么要进行数据转换,拿值类型例子说明一下, 比如:我们要把23角零钱,换成2.30元,就需要把整形 ...

  3. C++面向对象高级编程(四)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 一.Static 二.模板类和模板函数 三.namespace 一.Static 静态成员是“类级别”的,也就是它和类的地位等同,而普通成员是“ ...

  4. Unix环境高级编程(四)数据系统文件和信息

    本章主要介绍了Unix系统的正常运行要使用的与系统有关的数据文件和信息.如:口令文件,阴影文件.组文件.附加组.系统标识.时间和日期历程. 口令文件,即Unix系统用户数据库,存储在/etc/pass ...

  5. C#高级编程八十一天----捕获异常

    捕获异常 前面主要说了关于异常的一些基础和理论知识,没有进入到正真的异常案例,这一讲通过几个案例来描写叙述一下异常的捕获和处理. 案例代码: using System; using System.Co ...

  6. 【读书笔记】C#高级编程 第二十一章 任务、线程和同步

    (一)概述 所有需要等待的操作,例如,因为文件.数据库或网络访问都需要一定的时间,此时就可以启动一个新的线程,同时完成其他任务. 线程是程序中独立的指令流. (二)Paraller类 Paraller ...

  7. 【读书笔记】C#高级编程 第十一章 LINQ

    (一)LINQ概述 语言集成查询(Language Integrated Query,LINQ)在C#编程语言中继承了查询语法,可以用相同的语法访问不同的数据源. 1.LINQ查询 var query ...

  8. 《UNIX环境高级编程》笔记--更改用户ID和组ID

    在unix系统中,特权是基于用户和组ID的,当程序需要增加特权,或需要访问当前并不允许访问的资源时,我们需要更换自己 用户ID或组ID,使的新ID具有合适的特权或访问权限.与此类似,当程序需要降低其特 ...

  9. C#高级编程四十九天----队列

    队列 1.Queue定义 System.Collections.Queue类表示对象的先进先出集合,存储在Queue(队列)中的对象在一端插入,从还有一端移除. 2.长处 (1).能对集合进行顺序处理 ...

随机推荐

  1. LeetCode(60): 第k个排列

    Medium! 题目描述: 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" ...

  2. apache tomcat 集群!

    公司需要一个内部测试局域网, 要求可以支持3000并发访问!以前也没做过服务器这方面.临时抱佛脚,查看了N多文档,他人经验,布置好之后,又遇到了N多问题,功夫不负有心人.终于还是完成了要求!观他人的布 ...

  3. 超实用!!!使用IDEA插件Alibaba Cloud Toolkit工具一键部署本地应用到ECS服务器

    最近看到阿里云发布了一款名为 Alibaba Cloud Toolkit 的插件,可以帮助开发者高效开发并部署适合在云端运行的应用,瞬间击中了我的小心脏,这个对于个人开发者来说超级棒啊,终于不需要再手 ...

  4. poj 1511 正向 反向 构两个图

    有向图 源点为1 求源点到其他各点的最短距离之和 再在其他点到源点的最短距离之和 再加起来 多源点一终点 只要反向构图就行了 Sample Input 2 //T2 2 //结点数 边数1 2 13 ...

  5. hdu 2112 map+Dijkstra

    无向图 用map 起点和终点可能一样 数组不能开太大 WA了好多发 Sample Input6xiasha westlake //起点 终点xiasha station 60xiasha Shoppi ...

  6. python全栈开发day37-html

    web准备总结: 结构标准:相当于人的身体.html就是用来制作网页的. 表现标准: 相当于人的衣服.css就是对网页进行美化的. 行为标准: 相当于人的动作.JS就是让网页动起来,具有生命力的 1. ...

  7. Topic路由模式

    原本理解的不够彻底,程序总是不太对.所以查询了资料,关于这种模式的意思做了仔细的解读,复制的文字. 一:介绍 1.模式 2.知识点 其中,#可以匹配一个或者多个字符 其中,*可以匹配一个字符 3.仔细 ...

  8. ubuntu18.04 lts重装VMware Tools实现主机文件共享等功能

    ubuntu18.04 lts重装VMware Tools实现主机文件共享等功能 在VMWare 14.x上安装ubunuu18.04 lts后发现,可以实现全屏显示,但是没有与主机共享文件的功能,然 ...

  9. VS Code 配置 C/C++ 环境(转)

      写作原因 微软的 VSCode 一直以来为人诟病的一个问题就是对于 C/C++ 工程的编译以及调试支持度有限,配置起来比较复杂,但是 vscode-cpptools 团队经过一段时间的 bug 修 ...

  10. 洛谷 P1474 货币系统 Money Systems(经典)【完全背包】+【恰好装满的最大方案数量】

    题目链接:https://www.luogu.org/problemnew/show/P1474 题目描述 母牛们不但创建了它们自己的政府而且选择了建立了自己的货币系统.由于它们特殊的思考方式,它们对 ...