如何将字符串动态转换为指定的值类型
先看一个字符串动态转换的典型例子
如下函数 我们只知道value 是一个基本值类型 比如(System Int System Int System Double 等等) 或者是一个字符串类型 但我们无法在编码时确定这个value 具体是什么类型 它可能是由一个外部组件从某个数据源中读出来的基本类型中的一种类型的实例或者是字符串类型实例
这个函数希望实现比较value 是否在minValue maxValue这两个字符串对应的数值区间类 其中minValue 和 maxValue 构成一个闭区间 即
value in [minValue maxValue]
public static bool MyComparer(object value string minValue string maxValue)
要解决这个问题 我们需要解决两个基本问题
如何比较value 和 minValue maxValue
如何将minValue 和 maxValue 转换到value 对应的数据类型
首先我们来看如何进行比较
所有的基本值类型和string 类型都实现 IComparable这个接口 我们可以指定 value 为 IComparable 然后调用CompareTo来进行比较 不过这里有个问题 CompareTo 函数的参数obj 虽然是一个 object 类型 但这个 obj 的类型必须和 value 一致 否则将发生异常 也就是说我们不能把minValue 任意转换成某个类型比如 long 带进去 而需要将 minValue 和 maxValue 转换成和 value 一样的类型才行
下面我们就来讨论如何将字符串动态转换为指定的值类型
我们需要实现下面的函数
public static object ToType(Type type string value)
type 为指定的类型 value 为输入的字符串
首先我们知道所有的基本值类型都有一个叫 Parse 静态函数 我们只要把这个静态函数反射出来 就可以通过这个静态函数将字符串动态转换成对应的值类型
下面代码给出如何反射出这个静态函数 通过向对象type(Type类型)的GetMethods 函数输入 BindingFlags Static | BindingFlags Public 参数 我们可以枚举出这个类型所有的静态公共函数
然后我们判断这个函数的名称是否为 Parse 由于 Parse 函数有多个重载 但一个参数的重载只有 Parse (String)
所以我们需要判断mi 只有一个参数 这时取到的 mi 就是 Parse (String) 函数
MethodInfo parseMethod = null;
foreach (MethodInfo mi in type GetMethods(BindingFlags Static | BindingFlags Public)){if (mi Name == Parse && mi GetParameters() Length == ){parseMethod = mi;break;}}
接下来就是如何调用这个函数来动态转换字符串了
如下面代码 我们调用MethodInfo 的 Invoke 方法来动态调用这个函数 由于是静态函数 第一个参数 obj 传入null 并在第二个参数中带入value 这个参数
parseMethod Invoke(null new object[] { value });
下面给出字符串动态转换为指定类型的完整代码
using System;using System Collections Generic;using System Text;using System Reflection;
namespace Eagelt Convert{public class ConvertString{public static object ToType(Type type string value){if (type == typeof(string)){return value;}
MethodInfo parseMethod = null;
foreach (MethodInfo mi in type GetMethods(BindingFlags Static | BindingFlags Public)){if (mi Name == Parse && mi GetParameters() Length == ){parseMethod = mi;break;}}
if (parseMethod == null){throw new ArgumentException(string Format( Type: { } has not Parse static method! type));}
return parseMethod Invoke(null new object[] { value });}}}
MyComparer 函数的完整代码
public static bool MyComparer(object value string minValue string maxValue){IComparable parableObj = value as IComparable;
object min;object max;
if (parableObj == null){throw new ArgumentException(string Format( Type: { } does not inherit from IComparable value GetType()));}
min = ConvertString ToType(value GetType() minValue);max = ConvertString ToType(value GetType() maxValue);
return parableObj CompareTo(min) >= && parableObj CompareTo(max) <= ;
测试代码
Console WriteLine(MyComparer( ));Console WriteLine(MyComparer( ));Console WriteLine(MyComparer((byte) ));Console WriteLine(MyComparer((double) ));Console WriteLine(MyComparer( ));
测试结果
TrueFalseTrueFalseFalse
最后提一个简单的问题 供大家思考 如果我们需要将字符串动态转换成我们自己定义的复杂类型
如何实现呢?
比如我们有一个结构
struct UInt
{
public ulong Low;
public ulong High; }
我们将这个结构的实例对象传入到函数
Console WriteLine(MyComparer((UInt ) ));
lishixinzhi/Article/program/net/201311/11386