说起类型转换大家很容易的就会联想到将int类型转换成float类型或者是将double类型转转成int类型之类的转换。当然这可能是大多数人最先接触到的转换方式,也是最简单的转换方式。所谓转换就是从现有类型的值创建一个新的值,对于大多数面向对象的语言而言,因为多出了"类"这个概念,所以类型转换并不仅仅是基础类型(int、float、string等)之间的转换。.NET作为一个承载平台而言自然是需要提供适应多种情况的类型转换方式的,因此本文就结合自己的理解对.NET下的类型转换作一个简单的总结,如有错误,请各位不吝赐教!

 
 

一、.NET自动支持的类型转换

  • 基类型和派生类型之间的相互转换
  • 接口对象和实现接口类型的对象之间的相互转换

 
 

.NET除了自动支持基础类型之间的转换外还自动支持以上两种类型之间的转换。

至于基类、派生类和接口等概念想必无须过多赘述了。我们先定义一个简单的IPeople接口以及实现该接口的People类,然后再定义一个继承自People的ChinesePeople类。

 
 

public interface IPeople

{

        string Name { get; set; }

        int Age { get; set; }

}

 
 

  public class People:IPeople

{

        public
string Name { get; set; }

        public
int Age { get; set; }

        public
int Height { get; set; }

}

 
 

public class ChinesePeople : People

{

        public
string Country { get; set; }

}

 
 

由于.NET已经自动支持了以上两类的转换,因此我们可以作如下操作:

People people = new People();

ChinesePeople chinesePeople = new ChinesePeople();

people = chinesePeople;//派生类隐式转换成基类

chinesePeople = (ChinesePeople)people;//基类显示转换成派生类

 
 

IPeople ip = people;//实现接口的对象隐式转换成接口对象

people = (People)ip;//接口对象显示转换成实现接口的对象

 
 

以上两种转换都是比较简单的类型转换方式,也是在编程中会经常用到的。

 
 

二、基类型之间的转换:Convert

Convert是一个与语言无关的静态类,它为我们提供了一组类似ToXXX()形式的方法使得类型之间的转换变得非常简单。使用起来也很简单,例如:

Note:Convert类官方文档https://msdn.microsoft.com/zh-cn/library/system.convert(v=vs.110).aspx

 
 

 
 

三、自定义类型之间的转换:implicit(扩大、隐式转换)和explicit(缩小,显示转换)

上文已经说过,通过继承或者实现接口的方式我们可以对类型进行显示或隐式转换,那么问题来了,如果两个类型之间没有继承或者接口实现的关系,要怎么在这两个类型之间进行隐式或者显示转换呢?比如说我们再定义一个类型Dog

public class Dog

{

        public
string Name { get; set; }

        public
int Age { get; set; }

}

 
 

如果不进行任何操作直接将Dog类型的变量转换成People或者ChinesePeople类型的变量编译器肯定会抛出异常,就像下面这样,因为编译器无法将Dog类型的变量隐式或者显示的转换成People类型的变量

大家也可以这样理解,狗和人虽然都是动物,并且两者都有名字、年龄、身高等属性,所以从客观上来讲两者是不同的种类,不做任何操作的话是不能相互转换的。但是从主观来讲,张三做了对不起李四的事,李四可能就会认为张三他不是个人,他是条狗。这种情况是因为张三"做了一些事或者一些操作",所以李四才觉得他"可以"是条狗。下面就引入两个关键字implicit和explixit:

  • Implicit:扩大(隐式)转换,当前类型比目标类型具有更小的范围或成员列表(可以理解为基类比派生类具有更少的成员列表)
  • explicit:收缩(显示)转换,当前类型比目标类型具有更大的范围或成员列表(可以理解为派生类比基类具有更少的成员列表)

 
 

首先我们来看implicit关键字,implicit关键字可以定义类型的隐式转换,即如果要从People类型隐式转换成Dog类型的话我们需要对Dog类进行一些操作。

/// <summary>

/// 定义从People类型隐式转换成Dog类型的操作

/// </summary>

/// <param name="people">People类型的变量,保存People类型的数据</param>

public static implicit operator Dog(People people)

{

        Dog dog = new Dog();

        dog.Name = people.Name;

        dog.Age = people.Age;

        return dog;

}

上面的操作很简单,就是将People类型的一些数据赋值给Dog类型的变量,有了如上操作,我们就可以将People类型的变量隐式转换成Dog类型的变量而不会发生错误。

 
 

同理,一条可爱的小狗在某些人的眼里可能就像自己的亲人一样,因此狗"也可以当作"是人,但是也要做一些额外的"操作",比如给狗穿上一件好看的衣服或者剪个时髦的发型。。。所以狗需要"显示"转换成人。因此我们对People类型进行一些变换使得狗可以显示的转换成人。

public class People : IPeople

{

        public
string Name { get; set; }

        public
int Age { get; set; }

        public
int Height { get; set; }

 
 

        /// <summary>

        /// 定义从Dog类型隐式转换成People类型的操作

        /// </summary>

        /// <param name="dog">Dog类型的变量,保存Dog类型的数据</param>

        public static explicit operator People(Dog dog)

        {

                People people = new People();

                people.Name = dog.Name;

                people.Age = dog.Age;

                people.Height = 111;

                return people;

        }

}

有了上面的操作我们就可以将Dog类型变量显示转换成People类型的变量

Note:implicit和explicit两个关键字均是对"目标类型"进行操作,比如要将People类型隐式转换成Dog类型的话就要对Dog类型进行操作

 
 

四、IConvertible:自定义类型到CLR基类型之间的转换

上面已经介绍了基类型和自定义类型之间的相互转换,那么问题又来了,怎样把一个自定义类型转换成基类型?这种需求虽然不常见,但.NET作为一个平台而言自然是要尽量满足各种需求的。因此它为我们定义了一个IConvertible接口,该接口定义了向所有基类型转换的方法。

不仅如此,该接口还定义了一个返回实现类型的TypeCode方法以及将该类型转换成另一个类型的通用方法ToType。在实现向基类型转换的方法中我们就可以用到Convert静态类,因此IConvertible接口和Convert静态类的组合使得我们可以方便的定义自定义类型到基类型之间的转换。

Note:IConvertible接口的官方文档https://msdn.microsoft.com/zh-cn/library/system.iconvertible(v=vs.110).aspx

 
 

 
 

五、TypeConverter

除了上述几种类型转换方式之外,我们还可以通过TypeConverter为自定义类型定义转换器,通过使用TypeConverterAttribute使得自定义类型与转换器相关联。这种方式在WPF中比较常见。使用如下:

1.先定义一个类型转换器,转换器只重写了ConvertFrom和ConvertTo两个方法

public class PeopleConverter : TypeConverter

{

        public override
object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object
value)

        {

                if (value is string)

                {

                        string[] datas = ((string)value).Split(' ');

                        People people = new People();

                        people.Name = datas[0];

                        people.Age = Convert.ToInt32(datas[1]);

                        people.Height = Convert.ToInt32(datas[2]);

                        return people;

                }

                return base.ConvertFrom(context, culture, value);

        }

 
 

        public override
object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object
value, Type destinationType)

        {

                if (destinationType == typeof(string))

                {

                        People people = value as People;

                        return people.Name + " " + people.Age + " " + people.Height;

                }

                return base.ConvertTo(context, culture, value, destinationType);

        }

}

 
 

2.为自定义类关联转换器

 
 

经过上面两个步骤我们就可以这样来使用转换器:

输出如下:

 
 

TypeConverter类的具体用法参照官方文档https://msdn.microsoft.com/zh-cn/library/system.componentmodel.typeconverter(v=vs.110).aspx

 
 

.NET之类型转换的更多相关文章

  1. 为C# as 类型转换及Assembly.LoadFrom埋坑!

    背景: 不久前,我发布了一个调试工具:发布:.NET开发人员必备的可视化调试工具(你值的拥有) 效果是这样的: 之后,有小部分用户反映,工具用不了(没反应或有异常)~~~ 然后,建议小部分用户换个电脑 ...

  2. c# 基础 object ,new操作符,类型转换

    参考页面: http://www.yuanjiaocheng.net/webapi/config-webapi.html http://www.yuanjiaocheng.net/webapi/web ...

  3. Struts2日期类型转换

    针对日期类java.util.Date进行类型转换,要求客户端使用"yyyy-MM-dd","yyyy/MM/dd"中的任意一种输入,并以"yyyy- ...

  4. 【.NET深呼吸】基础:自定义类型转换

    照例,老周在开始吹牛之前,先讲讲小故事,这是朋友提出的建议,老TMD写技术有什么了不起的,人人都会写.后来老周想想,也确实,代码谁不会写,能写到有品位有感悟,就不容易做到.于是,老周接受了该朋友的建议 ...

  5. C++四种类型转换方式。

    类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单(TYPE)EXPRESSION,但是c风格的类型转换有不少的缺点,有的时候用c风格的转换是不合适的,因为它可以在任意类型之间转换,比 ...

  6. struts2类型转换

    1. Struts2中的类型转换 我们知道通过HTTP提交到后台的数据,都是字符串的形式,而我们需要的数据类型当然不只字符串类型一种.所以,我们需要类型转换! 在Struts2中,类型转换的概念除了用 ...

  7. C++_系列自学课程_第_11_课_类型转换_《C++ Primer 第四版》

    上次说了关于表达式的一些内容,说到还有一些关于数据类型转换的内容,今天我们接着八一八C++中的数据类型转换. 一.隐式类型转换 在表达式中,有些操作符可以对多种类型的操作数进行操作, 例如 + 操作符 ...

  8. Struts2入门(三)——数据类型转换

    一.前言 笔者一直觉得,学习一个知识点,你首先要明白,这东西是什么?有什么用?这样你才能了解.好了,不说废话. 1.1.类型转换为何存在?什么是类型转换? 在MVC框架中,都是属于表示层解决方案,都需 ...

  9. js条件判断时隐式类型转换

    Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...

  10. JavaScript中数据类型转换总结

    JavaScript中数据类型转换总结 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = " ...

随机推荐

  1. Ex1—vlookup

    VLOOKUP 的语法结构 整个计算机就相当于一门语言,首先我们就是要获取该函数的语法结构.以下是官网的语法结构 VLOOKUP(lookup_value, table_array, col_inde ...

  2. 图片src拼接后台返回ID

    本文地址:http://www.cnblogs.com/veinyin/p/8507403.html  在学习 CSS 时只了解了给固定地址,但是如果给的是一个需要拼接的地址就蒙了,以下是基于 Vue ...

  3. zzd 的割草机(Lawnmower)

    评测传送门 [题目描述] 已知花坛为一个 n * m 的矩形,草只会长在某些个格子上,zzd 有一个割草机,一开始,zzd 站在(1,1)处,面向(1,m)(面向右).每次 zzd 有两个选择(耗费一 ...

  4. php strcmp()函数

    <? $str = "LAMP"; $str1 = "LAMPBrother"; $strc = strcmp($str,$str1); switch ( ...

  5. Anaconda3+python3环境下如何创建python2环境(win+Linux下适用,同一个anaconda下py2/3共存)

    本人之前已经在anaconda环境下已经安装了python3的环境,现在因为一些需求,要安装python2环境 1.打开anaconda的anaconda prompt查看当前环境: conda in ...

  6. Java并发编程(3) JUC中的锁

    一 前言 前面已经说到JUC中的锁主要是基于AQS实现,而AQS(AQS的内部结构 .AQS的设计与实现)在前面已经简单介绍过了.今天记录下JUC包下的锁是怎么基于AQS上实现的 二 同步锁 同步锁不 ...

  7. 【驱动】USB驱动实例·串口驱动·键盘驱动【转】

    转自:http://www.cnblogs.com/lcw/p/3159370.html Preface USB体系支持多种类型的设备. 在 Linux内核,所有的USB设备都使用 usb_drive ...

  8. SSD固态硬盘检测工具AS SSD参数

    一. 使用AS SSD Benchmark进行查看 包括了4个方面的测试(顺序读写.4K随机读写.64线程4K读写.寻道时间) AS SSD的主要测试,也是网上最常见得到测试成绩的,是它主界面上持续. ...

  9. mysql -> 启动&多实例_03

    常用的连接方式: 套接字: mysql -uroot -p123 -S /application/mysql/tmp/mysql.sock Tcp/Ip: mysql -uroot -p123 -h ...

  10. Git如何设置多个用户

    前言 由于我们在使用GitHub时,通常不希望带有公司信息,所以需要独立的Git账户来提交练习代码,本文记录一下如何配置多个Git账户并创建公钥 正文 1.首先进入~/.ssh文件夹 2.然后创建一个 ...