编写高质量代码改善C#程序的157个建议——建议2: 使用默认转型方法
建议2: 使用默认转型方法
除了字符串操作外,程序员普遍会遇到的第二个问题是:如何正确地对类型实现转型。在上一个建议中,从int转型为string,我们使用了类型int的ToString方法。在大部分情况下,当需要对FCL提供的类型进行转型时,都应该使用FCL提供的转型方法。
这些转型方法包括:
使用类型的转换运算符。
使用类型内置的Parse、TryParse,或者如ToString、ToDouble和ToDateTime等方法。
使用帮助类提供的方法。
使用CLR支持的转型。
下面分别对这些方法进行说明。
1. 使用类型的转换运算符
使用类型的转换运算符,其实就是使用类型内部的一个方法(即函数)。转换运算符分为两类:隐式转换和显式转换(强制转换)。基元类型普遍都提供了转换运算符,如:
int i = ;
float j = ;
j = i; //int到float(Single)存在一个隐式转换
i = (int)j; //float(Single)到int存在,而且必须存在一个显式转换
注意 所谓“基元类型”,是指编译器直接支持的数据类型,即直接映射到FCL中的类型。基元类型包括sbyte、byte、short、 ushort、int、uint、long、ulong、char、float、double、bool、decimal、object、string。
用户自定义的类型也可以通过重载转换运算符的方式来提供这一类转换,代码如下所示:
class Program
{
static void Main(string[] args)
{
Ip ip = "192.168.0.96";
Console.WriteLine(ip.ToString());
}
} class Ip
{
IPAddress value; public Ip(string ip)
{
value = IPAddress.Parse(ip);
}
public static implicit operator Ip(string ip)
{
Ip iptemp = new Ip(ip);
return iptemp;
} public override string ToString()
{
return value.ToString();
}
}
在上面的代码中:
- Ip ip = "192.168.0.96";
提供的就是字符串到类型Ip之间的隐式转换。但是,除非考虑一些初始化值,一般不建议用户对自己的类型重载转换运算符。如果用户自定义的类型之间需要转换,建议从面向对象的角度考虑,因为它们一般都含有某种关系(如继承、实现等)。在这种情况下,就应该使用即将介绍的第四种方法:CLR支持的转型。 不过,我们仍需掌握FCL中的类型,尤其是基元类型之间的转换运算符,以便快速地在基元类型间进行转换。
2. 使用类型内置的Parse、TryParse,或者如ToString、ToDouble、ToDateTime等方法
在FCL中,如果某个类型经常需要进行转型操作,类型自身则会带有一些转型方法。比如从string转型为int,因为其经常发生,所以int本身就提供了Parse和TryParse方法。一般情况下,如果要对某类型进行转型操作,建议先查阅该类型的API文档。
3. 使用帮助类提供的方法
可以使用如System.Convert类、System.BitConverter类来进行类型的转换。
System.Convert提供了将一个基元类型转换为其他基元类型的方法,如ToChar、ToBoolean方法等。值得注意的 是,System.Convert还支持将任何自定义类型转换为任何基元类型,只要自定义类型继承了IConvertible接口就可以。如上文中的Ip 类,如果将Ip转型为string,除了重写Object的ToString方法外,还可以实现IConvertible的ToString方法,代码如 下所示:
- class Ip : IConvertible
- {
- //省略
- public bool ToBoolean(IFormatProvider provider)
- {
- throw new InvalidCastException("Ip-to-Boolean conversion is not supported.");
- }
- public string ToString(IFormatProvider provider)
- {
- return value.ToString();
- }
- //省略
- }
继承IConvertible接口必须同时实现其他转型方法,如上文中的ToBoolean,如果不支持此类转型,则应该抛出一个InvalidCastException,而不是一个NotImplementedException。
System.BitConverter提供了基元类型与字节数组之间相互转换的方法,这里不再赘述。
4. 使用CLR支持的转型
CLR支持的转型,即上溯转型和下溯转型。这个概念首先是在Java中提出来的,实际上就是基类和子类之间的相互转换,如图1-1所示。
在进行子类向基类转型的时候支持隐式转换,如Dog显然就是一个Animal;而当Animal转型为Dog的时候,必须是显式转换,因为Animal还可能是一个Cat,代码如下所示:
Animal animal;
Dog dog = new Dog();
animal = dog; //隐式转换,因为Dog就是Animal
//dog = animal; //编译不通过
dog = (Dog)animal; //必须存在一个显式转换
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
编写高质量代码改善C#程序的157个建议——建议2: 使用默认转型方法的更多相关文章
- 编写高质量代码改善C#程序的157个建议[1-3]
原文:编写高质量代码改善C#程序的157个建议[1-3] 前言 本文主要来学习记录前三个建议. 建议1.正确操作字符串 建议2.使用默认转型方法 建议3.区别对待强制转换与as和is 其中有很多需要理 ...
- 读书--编写高质量代码 改善C#程序的157个建议
最近读了陆敏技写的一本书<<编写高质量代码 改善C#程序的157个建议>>书写的很好.我还看了他的博客http://www.cnblogs.com/luminji . 前面部 ...
- 编写高质量代码改善C#程序的157个建议——建议157:从写第一个界面开始,就进行自动化测试
建议157:从写第一个界面开始,就进行自动化测试 如果说单元测试是白盒测试,那么自动化测试就是黑盒测试.黑盒测试要求捕捉界面上的控件句柄,并对其进行编码,以达到模拟人工操作的目的.具体的自动化测试请学 ...
- 编写高质量代码改善C#程序的157个建议——建议156:利用特性为应用程序提供多个版本
建议156:利用特性为应用程序提供多个版本 基于如下理由,需要为应用程序提供多个版本: 应用程序有体验版和完整功能版. 应用程序在迭代过程中需要屏蔽一些不成熟的功能. 假设我们的应用程序共有两类功能: ...
- 编写高质量代码改善C#程序的157个建议——建议155:随生产代码一起提交单元测试代码
建议155:随生产代码一起提交单元测试代码 首先提出一个问题:我们害怕修改代码吗?是否曾经无数次面对乱糟糟的代码,下决心进行重构,然后在一个月后的某个周一,却收到来自测试版的报告:新的版本,没有之前的 ...
- 编写高质量代码改善C#程序的157个建议——建议154:不要过度设计,在敏捷中体会重构的乐趣
建议154:不要过度设计,在敏捷中体会重构的乐趣 有时候,我们不得不随时更改软件的设计: 如果项目是针对某个大型机构的,不同级别的软件使用者,会提出不同的需求,或者随着关键岗位人员的更替,需求也会随个 ...
- 编写高质量代码改善C#程序的157个建议——建议153:若抛出异常,则必须要注释
建议153:若抛出异常,则必须要注释 有一种必须加注释的场景,即使异常.如果API抛出异常,则必须给出注释.调用者必须通过注释才能知道如何处理那些专有的异常.通常,即便良好的命名也不可能告诉我们方法会 ...
- 编写高质量代码改善C#程序的157个建议——建议152:最少,甚至是不要注释
建议152:最少,甚至是不要注释 以往,我们在代码中不写上几行注释,就会被认为是钟不负责任的态度.现在,这种观点正在改变.试想,如果我们所有的命名全部采用有意义的单词或词组,注释还有多少存在的价值. ...
- 编写高质量代码改善C#程序的157个建议——建议151:使用事件访问器替换公开的事件成员变量
建议151:使用事件访问器替换公开的事件成员变量 事件访问器包含两部分内容:添加访问器和删除访问器.如果涉及公开的事件字段,应该始终使用事件访问器.代码如下所示: class SampleClass ...
- 编写高质量代码改善C#程序的157个建议——建议150:使用匿名方法、Lambda表达式代替方法
建议150:使用匿名方法.Lambda表达式代替方法 方法体如果过小(如小于3行),专门为此定义一个方法就会显得过于繁琐.比如: static void SampeMethod() { List< ...
随机推荐
- bzoj 4555 [Tjoi2016&Heoi2016]求和——NTT+第二类斯特林数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4555 第二类斯特林数展开式: \( S(i,j) = \frac{1}{j!} \sum\l ...
- 当前标识(NT AUTHORITY\NETWORK SERVICE)没有对
报错:当前标识(NT AUTHORITY\NETWORK SERVICE)没有对C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP. ...
- AngularJS:过滤器
ylbtech-AngularJS:过滤器 1.返回顶部 1. AngularJS 过滤器 过滤器可以使用一个管道字符(|)添加到表达式和指令中. AngularJS 过滤器 AngularJS 过滤 ...
- ITextSharp使用说明 (转)
原文: http://www.cnblogs.com/LifelongLearning/archive/2010/12/28/1919138.html TextSharp是一个生成Pdf文件的开源项目 ...
- PHP实现四种基本排序算法 得多消化消化
1.冒泡排序 // 冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即,每当两相邻的数比较后发现它们的排序与排序 ...
- python开发模块基础:re正则
一,re模块的用法 #findall #直接返回一个列表 #正常的正则表达式 #但是只会把分组里的显示出来#search #返回一个对象 .group()#match #返回一个对象 .group() ...
- spring-cloud配置eureka客户端
spring-cloud配置eureka客户端 eureka用来发现其他程序 需要提前配置eureka服务端,具体看 https://www.cnblogs.com/ye-hcj/p/10292944 ...
- centos7 xfs 文件系统配置quota 用户磁盘配额
centos7的xfs配置 XFS是扩展性高.高性能的文件系统.也是rhel7/centos7的默认文件系统.XFS支持metadata journaling,这使其能从crash中更快速的恢复. ...
- QR 码的位置检测符
QR码的位置检测符由三个同心正方形叠加而成.分别为: 7*7 modules的黑色正方形: 5*5 modules的白色正方形 : 3*3modules的黑色正方形. 三个用于定位检测的“回”形符号应 ...
- Window setInterval() 方法
Window 对象 转自:https://www.w3cschool.cn/jsref/met-win-setinterval.html 定义和用法 setInterval() 方法可按照指定的周期( ...