.NET

万能转换器blqw.Convert(1)

2018-06-05  本文已影响21人  冰麟轻武

一、

曾经很长一段时间,我在写代码的时候特别烦类型转换
当时int.TryParse(string,out int)还没有out var的语法,所以每次写起来特别麻烦(不算大括号也要3行)
所以自己动手写了一个 Convert3
现在正在着手把它搬到standard上所以又有了Convert4(未发布)

二、

在设计这个组件之初,我就决定了,它的调用必须是简单的,简单的和简单的
在经过一些思考之后,我发现类型转换一般只有3个场景

  1. 转换对象,转换失败时抛出异常
  2. 转换对象,转换失败时返回默认值
  3. 转换对象,并以out方式返回转换是否成功

所以最终的组件,只有3个主要的转换方法
而且为了调用更简单,3个方法以扩展方法形式提供,使用重载实现
所以整个API其实只有1个 obj.To...

// 3个泛型
Convert3.To<T>(this object obj);                  //转换失败,抛出异常
Convert3.To<T>(this object obj, T defaultValue);  //转换失败,返回默认值
Convert3.To<T>(this object obj, out bool succeed);     //输出转换是否成功
//3个是非泛型 
Convert3.To(this object obj, Type outputType);
Convert3.To(this object obj, Type outputType, object defaultValue);
Convert3.To(this object obj, Type outputType, out bool succeed);

三、

调用

//假设有一个参数 object[] args 
var id = args[0].To(0); //泛型类型自动推断
var name = args[1].To("");
var birthday = args[2].To(DateTime.MinValue);
if (id < 0) 
    throw new Exception("id必须大于0");
if (strubg.IsNullOrWhiteSpace(name)) 
    throw new Exception("name不能为空");
if (birthday < new DateTime(1900,1,1) or birthday > DateTime.Today )
    throw new Exception("请填写正确的日期");

四、

基于以上结果的思考,决定程序主体采用外观模式设计

这种情况下使用外观模式其实有三种选择:

  1. 根据参数类型获得转换器,转换器中实现将指定类型转换为任意类型的功能
    interface IConvetor<in T>
    {
        object ConvertTo(T input);
    }
    
  2. 根据返回值类型获取转换器,转换器中实现将任意类型转为指定类型的功能
    interface IConvetor<out T>
    {
        T ConvertTo(object input);
    }
    
  3. 根据参数类型和返回值类型同时匹配转换器
    interface IConvetor<int TInput, out TOutput>
    {
        TOutput ConvertTo(TInput input);
    }
    

三总方式总的来说各有优缺点,在综合考虑了可读性,扩展性,性能及编码难度等因素后,最终选择了第2种方式来实现

未完待续

PS:如果文章可以帮到你,别忘了帮我点一下喜欢,让更多的人看到

上一篇下一篇

猜你喜欢

热点阅读