C#中的类型转换大总结

  使用C#一个最常见的问题便是各种类型间的转换。

  我们知道,C#中的类型分为值类型和引用类型两大类。但是,有关它们间各自转换的细节描述在网上很少得到详细的回答。现在,我结合搜索到的部分资料整理如下:

  1,问题

c#中类型转换的有两种,()转换和convert转换。

我想知道的是这两个转换的区别

还有就是()转换我用了发现好多不能转换过来,但是convert是万能转换的,那什么时候该用()什么时候该用convert呢?

最后问下子,把int sum 怎么用()转换成float类型?

请详细说明,最好有举例。

  解答:

(1)这两个方法的最大不同是它们对null值的处理方法:
Convert.ToInt32(null)会返回0而不会产生任何异常,但int.Parse(null)则会产生异常。

没搞清楚Convert.ToInt32和int.Parse()的细细微区别时千万别乱用,否则可能会产生无法预料的结果,举例来说:假如从url中取一个参数page的值,我们知道这个值是一个int,所以即可以用Convert.ToInt32(Request.QueryString["page"]),也可以用,int.Parse(Request.QueryString["page"]),但是如果page这个参数在url中不存在,那么前者将返回0,0可能是一个有效的值,所以你不知道url中原来根本就没有这个参数而继续进行下一下的处理,这就可能产生意想不到的效果,而用后一种办法的话没有page这个参数会抛出异常,我们可以捕获异常然后再做相应的处理,比如提示用户缺少参数,而不是把参数值当做0来处理。

(2)还有一点区别就是
a. Convert.ToInt32(double value)
如果 value 为两个整数中间的数字,则返回二者中的偶数;即 3.5转换为4,4.5 转换为 4,而 5.5 转换为 6。 不过4.6可以转换为5,4.4转换为4
b. int.Parse("4.5")
直接报错:"输入字符串的格式不正确".

c. int(4.6) = 4

Int转化其他数值类型为Int时没有四舍五入,强制转换

int.Parse是转换String为int
Convert.ToInt32是转换继承自Object的对象为int的.
你得到一个object对象,你想把它转换为int,用int.Parse就不可以,要用Convert.ToInt32.

个人总结:
(1)Convert.ToInt32的参数比较多,Int.Parse只能转换string类型的.
(2)Parse就是把String转换成int,char,double....等,也就是*.Parse(string) 括号中的一定要是string.
(3)Convert可以提供多种类型的转换,也就是Convert.*()括号中可以为很多种类型(包括string).

  2,问题: 如何使用 as 和 is 运算符安全地进行强制

  解答:
  首先,在MSDN(http://msdn.microsoft.com/zh-cn/library/cc488006.aspx)给出的解释非常简单,过于简单。

  更详细的解释如下:

  在程序中,进行类型转换是常见的事。那么在C#中支持以前语言的类型转换方法,即用类型名进行强行转换,例如:

objectbjTest =newNewType();

NewType newValue = (NewType)objTest;

  但是这样转换,有个严重的问题,就是在把objTest强转换成NewType类型对象的时候,这个过程是不安全的,因此需要用try-catch语句来进行保护。这样一来,比较安全的代码方式应该如下所示。

objectbjTest =newNewType();

NewType newValue =null;

try

{

newValue = (NewType)objTest;

}

catch( Exception err )

{

MessageBox.Show( err.Message );

}

  但是如上的写法在C#中已经属于过时的写法,而且也属于比较低效的写法。在C#中比较高效而且安全的写法,应该用as操作符,那么完成如上类似功能的正确代码应该如下。

objectbjTest =newNewType();

NewType newValue = objTestasNewType;

  那么很明显,如上的写法首先看起来很简便,至少代码数量和强转方式一样。至于安全性,对于as操作符来说,它不会做过的转换操作,当需要转换对象的类型属于转换目标类型或者转换目标类型的派生类型的时候,那么此转换操作才能成功,而且并不产生新的对象。

  因此用as来进行类型转换使安全的。为什么用as操作符进行类型转换的效率要高于老式的类型转换的,因为用as操作符进行转换就如前面所说的,首先判断当前对象的类型,当类型满足要求后才进行转换。而传统的类型转换方式,是用当前对象直接去转换,而且为了保护转换成功,要加上try-catch,这就决定了它的效率不会高于as操作符的效率。

  要注意的时候,不管用传统方式,还是用as操作符进行类型转换之后,在使用之前,需要进行判断转换是否成功,如下:

if( newValue!=null)

{

//Work with the object named "newValue"

}

  但是,使用as操作符有如下几点限制。

  第一个就是,不用在类型之间进行类型转化,即如下编写就会出现编译错误。

  第二个就是,不能应用在值类型数据,即不能如下写(也会出现编译错误)。

  对于第一点所提的,可以用传统的类型转换方式来完成,但是光用如下的方式,是不能正确完成。

NewTypeOne newTestOne =newNewTypeOne();

NewTypeTwo newTestTwo = (NewTypeTwo)newTestOne;

  但是光如上写是不能完成的,要想使如上的操作能正确完成,在原有类型中增加类型转换操作符函数,即需要完成类似如下的代码。

publicclassNewTypeOne

{

publicstatic explicitoperatorNewTypeTwo( NewTypeOne objTest )

{

//Convert object into new type 

}

}

  对于第二点所提的,在C#中可以使用is操作符,再加上老式的类型转换操作,就可以安全完成转换,那么要完成如上操作,正确的写法如下。

objectbjTest = 11;

if( objTestisint)

{

intnValue = (int)objTest;

}

  除了如上两点限制外,在用as操作符来进行类型转换的时候,有个细微的问题。在前面所说的,用as来进行类型转换的时候,所要转换的对象类型必须是目标类型或者转换目标类型的派生类型,那么这样就有个问题,即用as操作符来进行类型转换的时候无法转换成正确的类型,也就是说本来应该转换成子类型,却转换成了父类型。但是我并不认为这是个严重问题,因为在用as操作符来进行类型转换的时候,如何选择目标类型在编码的时候已经很明确了,即用父类型作为目标类型,那么类型转换的目的就是转换成父类型对象进行操作;反之亦然。

  在C#中已经提供了一个很好的类型转换方式,那么在进行类型转换的时候,可以按照如下的方式进行选择。

类型转换

使用选择

Object =>已知引用类型

使用as操作符来完成

Object =>已知值类型

先使用is操作符来进行判断,再用类型强转方式进行转换

已知引用类型之间转换

首先需要相应类型提供转换函数,再用类型强转方式进行转换

已知值类型之间转换

最好使用系统提供的Convert类所涉及的静态方法

objectbjTest = 11;

intnValue = objTestasint;
NewType newValue =newNewType();

NewType1 newValue = newValueasNewType1;

时间: 2024-10-26 14:31:34

C#中的类型转换大总结的相关文章

c++-C++中一个类型转换的问题。

问题描述 C++中一个类型转换的问题. //第一个 // Expression.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include #include"SeqStack.cpp" using std::cout; using std::endl; using std::cerr; double Operate(double a,char pre_op,double b); char Precede(char pre

《Java 7程序设计入门经典》一2.12 赋值中的类型转换

2.12 赋值中的类型转换 在编程中,常常需要将一种类型的变量赋值给另一种类型的变量.例如,要把int值赋给float变量,如: 当在一个赋值语句中有兼容的类型时,运算符右边的值自动转换为左边的类型.于是,在上面的代码片段中,变量i的值转换为float类型,然后赋给变量f.但是,由于Java有严格的类型检查,不是所有的类型都互相兼容,因此,不是所有的隐式转换都允许发生.例如,boolean类型与int类型就不兼容. 当把一种类型的数据赋给另一种类型的变量时,在以下情况下会发生自动类型转换(aut

c++-C#与C++位图保存方式的区别是什么?如何将C#中位图buffer正确传到C++代码中?求大神指导

问题描述 C#与C++位图保存方式的区别是什么?如何将C#中位图buffer正确传到C++代码中?求大神指导 C#中位图保存方式与C++中位图保存方式的区别是什么?如何将C#中位图buffer正确传到C++代码中?求大神指导 解决方案 C++中位图分为32/24/16位的三种位图数据存储方式,很多时候C++中主要使用32位和24位,如果你没有特别声明的话.C#中的位图 也多数是32位的.这些所谓的32位或者24位说的是位图中一个像素用多少位来表示,一个像素一般包含RGB三基色,也就是红(red)

学院观点:网页设计中的十大新错误

错误|设计|网页|网页设计 曾经我指出的网页设计中的十大错误,至今在很多站点上依然可见,并且影响着页面的可用性.也就是说,这三年来情况并未得到多大改善. 不幸的是,新的网络技术及其应用导致了一个全新层次的错误.以下是其中最严重的十个. 一. 破坏或减慢"后退"按钮 (我的看法:有时候对页面的适当控制是必须的.) "后退"按钮是网络用户的生命线,同时也是继超文本连接后最常使用的导航特征.用户可以随意尝试网页所指向的任何地方,而只需点击一两次"后退"

SEO优化过程中的十大陷阱之程序篇

小弟自从五年前接触SEO以来,每天都致力于SEO优化技术的学习与探讨中,成为了一名标准的职业SEOER,虽然这期间经历了这么长的时间,但由于自己的执行力实在是不敢恭维,所以直到现在手上还没有一个拿得出手.可以见人的不错的网站. 但尽管如此,五年的经验累积,五年的时间沉淀,让我在SEO行业里也能勉强算得上是一名先驱者.永远无法与昝辉老师那样的领军人物相提并论,也无法与华罡SEO的灵魂人物祝真老师相比,但这么长时间在SEO领域的摸爬滚打也让我对SEO有了自己的一份独特的见解. 从今天起就让我来为大家

Python中输出ASCII大文字、艺术字、字符字小技巧

  这篇文章主要介绍了Python中输出ASCII大文字.艺术字.字符字小技巧,本文首先给出了ASCII大文字.艺术字.字符字的图片效果,然后给出了Python中的实现方法,需要的朋友可以参考下 代码如下: display text in large ASCII art fonts 显示大ASCII艺术字体 这种东西在源码声明或者软件初始化控制台打印时候很有用. 例如下图: 这是查看HTML源码中截图而来,看到这种字体的网站名称,很cool,下面就介绍一下Python中如何输出这种字符字. 代码

t 遍历文件夹 ile nfo-急求使用Qt遍历打开文件夹,并把所有子文件的路径显示在ListWidget中,求大神帮忙!

问题描述 急求使用Qt遍历打开文件夹,并把所有子文件的路径显示在ListWidget中,求大神帮忙! bool StyleBatch::findFilePath(QString path){ QDir dir(path);if (!dir.exists()) return 0;dir.setFilter(QDir::Dirs|QDir::Files);dir.setSorting(QDir::DirsFirst);QFileInfoList list = dir.entryInfoList();

javaweb-通过request获取表单数据,但封装不到对象中,求大神解答!

问题描述 通过request获取表单数据,但封装不到对象中,求大神解答! # User类有username和password两个属性,封装的时候只能封装进去password,输出map的值的时候,里面是有的-- 以下是封装语句: User form = CommonUtils.toBean(request.getParameterMap(),User.class); 以下是CommonUtils类的toBean()方法:(不允许使用尖括号,泛型就用圆括号代替了-) public static (

c++-想用C++抽取txt文件中某标签对里面内容并保存到另外一个txt文件中,求大神帮助

问题描述 想用C++抽取txt文件中某标签对里面内容并保存到另外一个txt文件中,求大神帮助 A文件中,内容是这样的: [fullText]abcd[rating] [fullText]efg[rating] 我想要抽取[fullText] [rating]之间的内容,并将其保存到B文件中, 不同标签对的内容用空格隔开. 应该怎么写呢? 解决方案 正则表达式,解析出数据后保存 解决方案二: z字符串解析,截取对应位置子字符串. 解决方案三: 先分析行的内容,以回车换行符:如果确定 [fullTe