本文代码基于 .NET Framework 实现。

本来只想进行简单的配置存储的,不料发现 .NET 的基本类型多达十多种。于是,如果写成下面这样,那代码可就太多了哦:

// 注:`Configurator`是我的配置类,用于读写字符串的。
public static int GetInt32(this Configurator config, string key) { return int.Parse(config[key], CultureInfo.InvariantCulture); } public static void SetInt32(this Configurator config, string key, int value) { config[key] = value.ToString(CultureInfo.InvariantCulture); } public static bool GetBoolean(this Configurator config, string key) { return bool.Parse(config[key]); } // 还没完,这才 1.5 种而已。 // ……

尝试使用泛型

这些方法都比较相似,于是自然而然想到了泛型,所以写出了这段代码:

public static T GetValue<T>(this Configurator config, string key) where T : struct { var @string = config[key]; // T value = 某种通用的转换(@string); // 问题来了,这里该怎么写? return value; }

这里就郁闷了,因为虽然方法内部的实现都长得差不多,但他们之间除了名字相同之外(比如 ParseToString),并没有什么联系;这样,便不能使用统一的接口或者抽象类等等来调用。

尝试使用反射

既然名字类似,那自然又能想到反射。可是,拥有 Parse 的类型并不多,ToString 中能传入 CultureInfo.InvariantCulture 且参数顺序保持一致的类型也少的可怜。于是,反射只能保证写得出来代码,却并不能保证多种类型的支持。

另外想到一点,Int32 类型的 TryParse 中有 out 关键字修饰的参数,反射能否支持呢?StackOverflow 上找到了答案:

You invoke a method with an out parameter via reflection just like any other method. The difference is that the returned value will be copied back into the parameter array so you can access it from the calling function.

object[] args = new object[] { address, request }; _DownloadDataInternal.Invoke(this, args); request = (WebRequest)args[1];

意思是说,这在反射中不用作什么考虑,传入的参数数组天然就已经支持了 out 关键字。

尝试寻找更通用的方案

在 Google 上继续漫游,在 StackOverflow 上发现这篇讨论:How to convert string to any type。

最高票答案给出的回复是:

using System.ComponentModel;TypeConverter typeConverter = TypeDescriptor.GetConverter(propType);
object propValue = typeConverter.ConvertFromString(inputValue);

这可打开了思路,原来 .NET Framework 内部已经有了这种转换机制和相关的方法。于是用这种方法修改我的方法,成了这样子:

public static T GetValue<T>(this Configurator config, string key) where T : struct { var @string = config[key]; var td = TypeDescriptor.GetConverter(typeof (T)); return (T) td.ConvertFromInvariantString(@string); } public static void SetValue<T>(this Configurator config, string key, T value) where T : struct { var td = TypeDescriptor.GetConverter(typeof (T)); var @string = td.ConvertToInvariantString(value); config[key] = @string; }

编写单元测试发现,这种方法能够支持的类型真的非常多,byte char short ushort int uint long ulong bool float double decimal DateTime Point Vector Size Rect Matrix Color……

看看代码中 TypeDescriptor.GetConverter 的返回值发现是 TypeConverter 类型的,而我们在 WPF 的 xaml 中编写自定义类型时,经常需要执行此类型的 TypeConverter。凭这一点可以大胆猜测,xaml 中能够通过字符串编写的类型均可以通过这种方式进行转换。然而,目前我还为对此进行验证。

验证猜想

  1. 去 https://referencesource.microsoft.com/ 看 TypeDescriptor.GetConverter 的源码(点击进入)。
  2. 尝试自定义一个类型,在类型上标记 TypeConverter,并对此类进行测试。

转载于:https://www.cnblogs.com/walterlv/p/6294106.html

利用 TypeConverter,转换字符串和各种类型只需写一个函数相关推荐

  1. c语言的十进制转十六进制字符串,用c语言写一个函数把十进制转换成十六进制,该如何处理...

    用c语言写一个函数把十进制转换成十六进制 用c语言写一个函数把十进制转换成十六进制 网上找到一些,感觉有占乱 分享到: ------解决方案-------------------- #include ...

  2. 腾讯视频QLV格式转换成mp4格式,只需这样做!

    到百度首页百度首页登录 腾讯视频QLV格式转换成mp4格式,只需这样做! 淡定人生 百家号17-10-1603:44 腾讯视频单独弄了一个qlv格式,一定程度上也造成了我们使用时的不便利.这几天有个朋 ...

  3. c语言中如何将字符串转成16进制,用c语言写一个函数把十进制转换成十六进制,该如何处理...

    用c语言写一个函数把十进制转换成十六进制 用c语言写一个函数把十进制转换成十六进制 网上找到一些,感觉有占乱 分享到: ------解决方案-------------------- #include ...

  4. 金山笔试题-字符串排序 : 写一个函数,实现对给定的字符串(字符串里面包括:英文字母,数字,符号)的处理...

    写一个函数,实现对给定的字符串(字符串里面包括:英文字母,数字,符号)的处理.经过处理后的字符串其内容按字母,数字,符号的顺序存放.函数声明如下: void ParseString(char* pst ...

  5. 氮化镓HUB,把氮化镓适配器于HUB合为一体,带笔记本出去只需带一个适配器就够了

    氮化镓HUB,把氮化镓适配器于HUB合为一体,带笔记本出去只需带一个适配器就够了 随着今年各大手机知名厂商推出氮化镓适配器,算是把氮化镓带火了. 氮化镓作为一种新型半导体材料比传统比传统硅机电源IC芯 ...

  6. C语言---写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串

    题目: 写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串. #include <string.h> #include <stdio.h> void left_re ...

  7. 写一个函数,2 个参数,1 个字符串,1 个字节数,返回截取的字符串,要求字符串中的中文不能出现乱码

    题目要求: 写一个函数,2 个参数,1 个字符串,1 个字节数,返回截取的字符串,要求字符串中的中文不能出现乱码. 如("我ABC",4)应该截为"我AB", ...

  8. 写一个函数,输入int型,返回整数逆序后的字符串

    2019独角兽企业重金招聘Python工程师标准>>> 刚刚看到一个面试题:写一个函数,输入int型,返回整数逆序后的字符串.如:输入123,返回"321". 要 ...

  9. 编写一个C程序,实现以下功能:用一个函数实现两个字符串的比较,即自己写一个strcmp函数,函数原型为:int strcmp(char *p1,char *p2);设p1指向字符串s

    题目描述: 编写一个C程序,实现以下功能: 用一个函数实现两个字符串的比较,即自己写一个strcmp函数,函数原型为: int strcmp(char *p1,char *p2); 设p1指向字符串s ...

  10. (14)写一个函数,将两个字符串连接

    写一个函数,将两个字符串连接 程序分析:用户在控制台输出第一个字符串后按下回车键继续输出下一个字符串.需要加上getchar()读取换行符,若不进行处理程序会将换行符也连接到新的字符串中. #incl ...

最新文章

  1. oracle rman imp exp,Oracle-client支持exp|imp|rman
  2. 怎么用python制作简单的程序-神级程序员教你如何用python制作一个牛逼的外挂!...
  3. 【项目实战课】基于Pytorch的StyleGAN人脸属性(表情、年龄、性别)编辑实战
  4. java语言如何跳转界面_在java中spring mvc页面如何跳转,详细图解
  5. mysql int 最大显示宽度_mysql int 整数类型 解释显示宽度 和 存储宽度
  6. win7系统还原在哪​
  7. 看看人家架构师那消息队列中间件玩的,那叫一个优雅!
  8. python中常用的九种预处理方法
  9. c++自动抢购_小黄人汽车手机支架多功能出风口高档可充电全自动导航卡通支架2元优惠券券后价22.9元...
  10. 【图像边缘检测】基于matlab元胞自动机图像边缘检测【含Matlab源码 427期】
  11. 机器学习-学习笔记3.1-局部加权回归
  12. mysql5.6怎样测试_Mysql5.6 字符集设置测试
  13. 【ODBC】ODBC连接数据库详细说明
  14. linux hdparm 测试磁盘io,Linux测试硬盘读写速度之hdparm命令
  15. linux 删除用户 currently logged in,Linux执行usermod时提示user xxx is currently logged in
  16. Mongodb被黑经历
  17. java web 打印 Cl0dup
  18. 张小龙:从FoxMail到WeChat
  19. 【漏洞复现】Moniker禁用绕过漏洞|ole逻辑漏洞(CVE-2017-8570)
  20. 兔老大的系统设计(一)健康度系统

热门文章

  1. GNN | 最新2022综述
  2. 在文本和图像上的对比学习小综述~
  3. 详解文本分类之多通道CNN的理论与实践
  4. 深度学习框架如何优雅的做算子对齐任务?
  5. 只用两行代码,我让Transformer推理加速了50倍
  6. 【每日算法Day 108】一道简单的二叉树题目,写法还是挺多的。
  7. 每日算法系列【LeetCode 1031】两个非重叠子数组的最大和
  8. python—scipy.stats.multivariate_normal
  9. 基于Pytorch实现CNN卷积神经网络-Mnist数据集
  10. 云网络开山之作,揭秘云上高速公路的十年技术成果!