编写高质量代码改善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< ... 
随机推荐
- 平均分割list
			private static List<List<Integer>> splitList(List<Integer> lists,int limit){ int s ... 
- leetcode 21.Merge Two Sorted Lists ,java
			题目: Merge two sorted linked lists and return it as a new list. The new list should be made by splici ... 
- python urllib和urllib3包
			urllib.request urllib当中使用最多的模块,涉及请求,响应,浏览器模拟,代理,cookie等功能. 1. 快速请求 urlopen返回对象提供一些基本方法: read 返回文本数据 ... 
- laravel中session的过期时间
			在项目开发的过程中,前后端分离 需要用session保存用户的登陆信息 这就涉及到session的有效期了 session又分为php中的session有效期和laravel中的session的有效期 ... 
- pytest命令行选项
			-m 标记 代码加一个装饰器:@pytest.mark.run_bbc_test,命令行添加 -m run_bbc_test,执行带@pytest.mark.run_bbc_test的测试用例: -k ... 
- oracle11.2 安装
			win10安装oracle 11g 时出现INS-13001环境不满足最低要求 oracle在win10上安装教程 
- oracle 11g r2 使用rman进行迁移rac到rac
			源端服务器主机名 rac05 rac06公共IP地址(eth0) 10.15.8.15 10.15.8.16 虚拟IP地址(eth0) 10.15.8.17 10.15.8.18私有IP地址(eth1 ... 
- (转)Docker - 创建 Docker overlay network (containers 通信)
			原文链接: http://www.cnblogs.com/AlanWalkOn/p/6101875.html --- 创建基于Key-Value的Docker overlay network. 这样运 ... 
- C Primer Plus学习笔记(十三)- 结构和其他数据形式
			建立结构声明 结构声明(structure declaration)描述了一个结构的组织布局 struct book { char title[MAXTITL]; char author[MAXAUT ... 
- Flask之自定义模型类
			4.3自定义模型类 定义模型 模型表示程序使用的数据实体,在Flask-SQLAlchemy中,模型一般是Python类,继承自db.Model,db是SQLAlchemy类的实例,代表程序使用的数据 ... 
