2012年9月6日 星期四

C# - 如何知道泛型的型態?

因為某種需要,所以開了一個 table ,
在裡面的開了一個 varchar 的欄位,
雖然是 varchar 的型態,
但是實際上會存入各種資料型態 bool, int, decimal, string...
原本以前的笨蛋寫法會是像是下面這種直接回傳字串的宣告,


public string GetOptionValue(string optionName)


然後呼叫的人再去把字串轉型成自己要的型態。

不過我是一個很懶的人,
所以我想說如果每次要用的人都自己還要轉型,
我實在是很懶得每次都還要寫一樣的 code ,
雖然可能只是多了一行,但是我就是不爽寫!
那可以怎麼做呢?
這個時候我想到了也許可以利用泛型來處理,
泛型的宣告如下,


public T GetOptionValue<T>(string optionName)




不過尷尬的是...
以前用泛型的時候其實我們所要的資料型態跟我們得到的資料型態是一致的,
有點繞口,例如我們會寫成下面那樣,


Tables[0].Rows[0].Field<T>(0);


例如我們要的是某個 varchar 的欄位,
所以我們 T 會傳入 string ,而且 Field(0) 也的確是 string 的型態,
所以這邊就是我剛剛所說的泛型的型態與得到的資料型態是一致的;

然後現在這邊的問題是...
不管我 T 是傳入甚麼型態,
資料庫回傳的欄位都是 varchar ,
所以看來我必須依據 T 的型態來做轉型,
問題是...我該怎麼知道 T 的型態是甚麼?
這種問題就是知道的人就知道,不知道的人就怎麼樣都不會寫,
嘟嘟好我就是不知道的那個人 = =;
不過還好我估狗的關鍵字下的還不錯,
所以找到了一篇文章有提到,
我們可以用下面的 code 得到 T 的型態,


Type.GetTypeCode(typeof(T))


得到型態之後我們就可以把 string 轉型成 T 的型態,寫法如下:


(T)(object)Convert.ToBoolean(o);


很不習慣這樣的寫法,所以沒寫過的人應該很難寫出這樣的 code 吧?

整個程式碼如下:


switch (Type.GetTypeCode(typeof(T)))
{
    case TypeCode.Boolean: return (T)(object)Convert.ToBoolean(o);
    case TypeCode.Byte: return (T)(object)Convert.ToByte(o);
    case TypeCode.Char: return (T)(object)Convert.ToChar(o);
    case TypeCode.DateTime: return (T)(object)Convert.ToDateTime(o);
    case TypeCode.Decimal: return (T)(object)Convert.ToDecimal(o);
    case TypeCode.Double: return (T)(object)Convert.ToDouble(o);
    case TypeCode.Int16: return (T)(object)Convert.ToInt16(o);
    case TypeCode.Int32: return (T)(object)Convert.ToInt32(o);
    case TypeCode.Int64: return (T)(object)Convert.ToInt64(o);
    case TypeCode.SByte: return (T)(object)Convert.ToSByte(o);
    case TypeCode.Single: return (T)(object)Convert.ToSingle(o);
    case TypeCode.String: return (T)(object)Convert.ToString(o);
    default: return (T)o;
}



沒有留言:

張貼留言