新聞中心
先看一個(gè)字符串動(dòng)態(tài)轉(zhuǎn)換的典型例子

如下函數(shù),我們只知道value 是一個(gè)基本值類(lèi)型,比如(System.Int32, System.Int16, System.Double 等等) 或者是一個(gè)字符串類(lèi)型。但我們無(wú)法在編碼時(shí)確定這個(gè)value 具體是什么類(lèi)型,它可能是由一個(gè)外部組件從某個(gè)數(shù)據(jù)源中讀出來(lái)的基本類(lèi)型中的一種類(lèi)型的實(shí)例或者是字符串類(lèi)型實(shí)例。
這個(gè)函數(shù)希望實(shí)現(xiàn)比較value 是否在minValue, maxValue這兩個(gè)字符串對(duì)應(yīng)的數(shù)值區(qū)間類(lèi),其中minValue 和 maxValue 構(gòu)成一個(gè)閉區(qū)間,即
value in [minValue, maxValue] |
要解決這個(gè)問(wèn)題,我們需要解決兩個(gè)基本問(wèn)題。
1. 如何比較value 和 minValue, maxValue
2. 如何將minValue 和 maxValue 轉(zhuǎn)換到value 對(duì)應(yīng)的數(shù)據(jù)類(lèi)型
首先我們來(lái)看如何進(jìn)行比較
所有的基本值類(lèi)型和string 類(lèi)型都實(shí)現(xiàn) IComparable這個(gè)接口。我們可以指定 value 為 IComparable,然后調(diào)用CompareTo來(lái)進(jìn)行比較。不過(guò)這里有個(gè)問(wèn)題,CompareTo 函數(shù)的參數(shù)obj 雖然是一個(gè) object 類(lèi)型,但這個(gè) obj 的類(lèi)型必須和 value 一致,否則將發(fā)生異常。也就是說(shuō)我們不能把minValue 任意轉(zhuǎn)換成某個(gè)類(lèi)型比如 long 帶進(jìn)去,而需要將 minValue 和 maxValue 轉(zhuǎn)換成和 value 一樣的類(lèi)型才行。
下面我們就來(lái)討論如何將字符串動(dòng)態(tài)轉(zhuǎn)換為指定的值類(lèi)型
我們需要實(shí)現(xiàn)下面的函數(shù):
public static object ToType(Type type, string value) |
type 為指定的類(lèi)型,value 為輸入的字符串。
首先我們知道所有的基本值類(lèi)型都有一個(gè)叫 Parse 靜態(tài)函數(shù),我們只要把這個(gè)靜態(tài)函數(shù)反射出來(lái),就可以通過(guò)這個(gè)靜態(tài)函數(shù)將字符串動(dòng)態(tài)轉(zhuǎn)換成對(duì)應(yīng)的值類(lèi)型。
下面代碼給出如何反射出這個(gè)靜態(tài)函數(shù)。通過(guò)向?qū)ο髏ype(Type類(lèi)型)的GetMethods 函數(shù)輸入 BindingFlags.Static
| BindingFlags.Public 參數(shù),我們可以枚舉出這個(gè)類(lèi)型所有的靜態(tài)公共函數(shù)。
然后我們判斷這個(gè)函數(shù)的名稱(chēng)是否為 "Parse" ,由于 Parse 函數(shù)有多個(gè)重載,但一個(gè)參數(shù)的重載只有 Parse (String)
所以我們需要判斷mi 只有一個(gè)參數(shù),這時(shí)取到的 mi 就是 Parse (String) 函數(shù)。
MethodInfo parseMethod = null; |
接下來(lái)就是如何調(diào)用這個(gè)函數(shù)來(lái)動(dòng)態(tài)轉(zhuǎn)換字符串了。
如下面代碼,我們調(diào)用MethodInfo 的 Invoke 方法來(lái)動(dòng)態(tài)調(diào)用這個(gè)函數(shù),由于是靜態(tài)函數(shù),第一個(gè)參數(shù) obj 傳入null. 并在第二個(gè)參數(shù)中帶入value 這個(gè)參數(shù)。
parseMethod.Invoke(null, new object[] { value }); |
下面給出字符串動(dòng)態(tài)轉(zhuǎn)換為指定類(lèi)型的完整代碼
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 == 1)
{
parseMethod = mi;
break;
}
}if (parseMethod == null)
{
throw new ArgumentException(string.Format(
"Type: {0} has not Parse static method!", type));
}return parseMethod.Invoke(null, new object[] { value });
}
}
}
MyComparer 函數(shù)的完整代碼
public static bool MyComparer(object value, string minValue, string maxValue)
{
IComparable comparableObj = value as IComparable;object min;
object max;if (comparableObj == null)
{
throw new ArgumentException(string.Format(
"Type: {0} does not inherit from IComparable", value.GetType()));
}min = ConvertString.ToType(value.GetType(), minValue);
max = ConvertString.ToType(value.GetType(), maxValue);return comparableObj.CompareTo(min) >= 0 && comparableObj.CompareTo(max) <= 0;
}
測(cè)試代碼
Console.WriteLine(MyComparer(2, "1", "3"));
Console.WriteLine(MyComparer(3, "1", "2"));
Console.WriteLine(MyComparer((byte)2, "1", "3"));
Console.WriteLine(MyComparer((double)3, "1", "2"));
Console.WriteLine(MyComparer("3", "1", "2"));
測(cè)試結(jié)果
True |
最后提一個(gè)簡(jiǎn)單的問(wèn)題,供大家思考,如果我們需要將字符串動(dòng)態(tài)轉(zhuǎn)換成我們自己定義的復(fù)雜類(lèi)型,如何實(shí)現(xiàn)呢?
比如我們有一個(gè)結(jié)構(gòu)
struct UInt128 |
我們將這個(gè)結(jié)構(gòu)的實(shí)例對(duì)象傳入到函數(shù)
Console.WriteLine(MyComparer((UInt128)2, "1", "3")); |
這樣可以嗎?怎樣做才能做到呢?
文章標(biāo)題:如何將字符串動(dòng)態(tài)轉(zhuǎn)換為指定的值類(lèi)型
分享路徑:http://m.fisionsoft.com.cn/article/dpoogco.html


咨詢(xún)
建站咨詢(xún)
