HTML5技术

.Net下一个类型转换神器 - jiulang

字号+ 作者:H5之家 来源:博客园 2015-12-08 08:12 我要评论( )

引言 类型转换经常遇到,最常用的应该是string类型转换为其它基元类型,常见于http参数类型转换。Convert静态类的Convert.ChangeType()方法可以把实现IConvertible接口的类型转换为其它也实现这个接口的类型,也等同于里面的ToInt32()、To Decimal()等方法的

引言

类型转换经常遇到,最常用的应该是string类型转换为其它基元类型,常见于http参数类型转换。Convert静态类的Convert.ChangeType()方法可以把实现IConvertible接口的类型转换为其它也实现这个接口的类型,也等同于里面的ToInt32()、ToDecimal()等方法的功能,但不支持转换到这类型的可空类型,因为Nullable<>类型并没有实现IConvertible这个接口;此外JavaScriptSerializer.ConvertToType()这个方法相对强大,支持转换到Nullable<>类型、字符串到枚举,也支持IDictionary<string,object>类型转换为对象,居于原因,是为了JavaScriptSerializer在反序列化JSON为动态类型后,能把这些类型进行转换为常见类型,但JavaScriptSerializer.ConvertToType方法不能扩展。

神器来了 名称:

今天主角转换器叫Converter,这是花费我几天时间才琢磨出来。

点再下载代码(也要点个赞哦)

功能:

今它支持基础类型、decimal、guid和枚举相互转换以及这些类型的可空类型和数组类型相互转换,支持字典和DynamicObject转换为对象以及字典和DynamicObject的数组转换为对象数组。

扩展性:

可以增加其它类型转换,或修改某种转换规则,也就是说转换器是支持功能部分重写和功能扩展的,功能移除也支持,比如想干掉DynamicObject类型的转换也可以。

神器使用方法

1、使用静态方法,Converter.Cast(object value,Type targetType)或其泛型方法 :Converter.Cast<int?[]>(new[] {null, "2" }

2、实例化来调用,new Converter().Convert(new[] { null, "2" }, typeof(int?));

 

Converter的扩展

扩展是灵魂,如果没有扩展功能,这东东和JavaScriptSerializer.ConvertToType()有啥区别,Converter在扩展方面下了一翻功夫。转换器里包含多个转换单元,这些单元可以增加、删除、替换和调整顺序,自定义的单元,可以从已有单元派生,也可以完整实现,然后插入到转换器的转换单元管理器中,转换器就升级了。而转换单元本身也能调用转换器来转换,这就形成一种可扩展的递归。

关系代码如下:

类型转换 Converter() { this.Items = new ContertItems() .AddLast<NoConvert>() .AddLast<NullConvert>() .AddLast<PrimitiveContert>() .AddLast<NullableConvert>() .AddLast<DictionaryConvert>() .AddLast<ArrayConvert>() .AddLast<DynamicObjectConvert>(); }

转换器由转换单元组成

定义类型转换单元 IConvert { 将value转换为目标类型 /// 并将转换所得的值放到result /// 如果不支持转换,则返回false Convert(Converter converter, object value, Type targetType, out object result); }

转换单元可以调用转换器


删除转换单元:

var converter = new Converter(); converter.Items.Remove<DynamicObjectConvert>();

增加转换单元:

编写一个单元,实现IConvert接口,比如 class JObjectConvert:IConvert{},然后就可以把这个转换单元添加到转换器实例中,

var converter = new Converter(); converter.Items.AddFrist<JObjectConvert>();

转换单元重写:

比如从string转换为decimal类时,要求5位小数,我们可以写一个单元,class MyPrimitiveContert:PrimitiveContert{},然后改写里面的Convert方法,再把MyPrimitiveContert替换转换器里的PrimitiveContert单元

var converter = new Converter(); converter.Items.Replace<PrimitiveContert, MyPrimitiveContert>();

后记

之所以写这个东西,是因为我的NetworkSocket组件里websocket部分很需要一个灵活的类型转换器,客户端发送{api:"login",parameters:[{account:"admin",password:"123456"}]}这样结构的Json给服务器,服务要解析这个json然后反射执行Login(Userinfo user)这个方法。

这里parameters数组里内容的类型是根据api的名称而定的,而要解析到api的内容,又要知道整个json的结构,形成蛋和鸡。只有将json解析为动态类型,才能满足要求,而JavaScriptSerializer反序列化为动态类型时,实际上是json对象转换为字典,json数组转换为ArrayList,其它基本类型差不多一一对应,枚举类型看情况;如果使用Json.Net解析,json对象转换为JObject动态类型,json数组转换为JArray,一些基本类型一般会对应JValue。

当把序列化和反序列化抽象或定义为接口的时候,JavaScriptSerializer.Converter方法就无力了,它没法转换JObject这些类型,也没有扩展的入口点,还有就是在.net core上也用不了。而Converter只需要添加一个单元转换单元,用来实现Json.Net里面几个动态类型转换为Api参数的类型,就可以达到完美的转换效果。

 

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    Dora.Interception: 一个为.NET Core度身定制的AOP框架 - Artech

    2017-05-02 11:00

  • 如何在 ASP.NET Core 中发送邮件 - Savorboard

    如何在 ASP.NET Core 中发送邮件 - Savorboard

    2017-05-02 08:02

  • 十二个 ASP.NET Core 例子 - Savorboard

    十二个 ASP.NET Core 例子 - Savorboard

    2017-04-27 16:01

  • ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    2017-04-24 08:04

网友点评
q