熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

如何將字符串動態轉換為指定的值類型

2013-11-13 09:42:38  來源: .NET編程 

  先看一個字符串動態轉換的典型例子

  如下函數我們只知道value 是一個基本值類型比如(SystemInt SystemInt SystemDouble 等等) 或者是一個字符串類型但我們無法在編碼時確定這個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 函數輸入 BindingFlagsStatic
| BindingFlagsPublic 參數我們可以枚舉出這個類型所有的靜態公共函數

  然後我們判斷這個函數的名稱是否為 Parse 由於 Parse 函數有多個重載但一個參數的重載只有 Parse (String)

  所以我們需要判斷mi 只有一個參數這時取到的 mi 就是 Parse (String) 函數

  

  MethodInfo parseMethod = null;

  foreach (MethodInfo mi in typeGetMethods(BindingFlagsStatic
| BindingFlagsPublic))
{
if (miName == Parse && miGetParameters()Length == )
{
parseMethod = mi;
break;
}
}

  接下來就是如何調用這個函數來動態轉換字符串了

  如下面代碼我們調用MethodInfo 的 Invoke 方法來動態調用這個函數由於是靜態函數第一個參數 obj 傳入null 並在第二個參數中帶入value 這個參數

  

  parseMethodInvoke(null new object[] { value });

  下面給出字符串動態轉換為指定類型的完整代碼

  

  

  using System;
using SystemCollectionsGeneric;
using SystemText;
using SystemReflection;

  namespace EageltConvert
{
public class ConvertString
{
public static object ToType(Type type string value)
{
if (type == typeof(string))
{
return value;
}

  MethodInfo parseMethod = null;

  foreach (MethodInfo mi in typeGetMethods(BindingFlagsStatic
| BindingFlagsPublic))
{
if (miName == Parse && miGetParameters()Length == )
{
parseMethod = mi;
break;
}
}

  if (parseMethod == null)
{
throw new ArgumentException(stringFormat(
Type: {} has not Parse static method! type));
}

  return parseMethodInvoke(null new object[] { value });
}
}
}

  MyComparer 函數的完整代碼

  

  

  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(stringFormat(
Type: {} does not inherit from IComparable valueGetType()));
}

  min = ConvertStringToType(valueGetType() minValue);
max = ConvertStringToType(valueGetType() maxValue);

  return comparableObjCompareTo(min) >= && comparableObjCompareTo(max) <= ;

  測試代碼

  ConsoleWriteLine(MyComparer( ));
ConsoleWriteLine(MyComparer( ));
ConsoleWriteLine(MyComparer((byte) ));
ConsoleWriteLine(MyComparer((double) ));
ConsoleWriteLine(MyComparer( ));

  測試結果

  

  True
False
True
False
False

  最後提一個簡單的問題供大家思考如果我們需要將字符串動態轉換成我們自己定義的復雜類型

  如何實現呢?

  比如我們有一個結構

  

  struct UInt

  {

  public ulong Low;

  public ulong High;
}

  我們將這個結構的實例對象傳入到函數

  

  ConsoleWriteLine(MyComparer((UInt) ));

  這樣可以嗎?怎樣做才能做到呢?


From:http://tw.wingwit.com/Article/program/net/201311/11386.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.