Public Function GenericCast(Of U, V)(ByVal obj As U) As V Return CType(obj, V) End Function 除非我們加以約束U是V的子類。這顯然是為了類型安全做出的考慮,因為.NET這種跨程序集的泛型無法在編譯時做出足夠的檢查來確保類型安全。但是限制了這種操作,就妨礙了我們做事,很多代碼因此寫不出來。于是,我們可以利用.NET所有類型的基類Object來繞過這一限制:
Public Function GenericCast(Of U, V)(ByVal obj As U) As V Return CType(DirectCast(obj, Object), V) End Function 現在,GenericCast泛型方法就能執行int與double等內置規則的轉換了。很神奇?因為CType運算符在編譯時自動調用了VB運行庫的轉換函數,該函數在運行期間對泛型類型參數的真實類型做了檢查。而且這個過程的性能完全可以接受。
static V GenericCast<U, V>(U obj) { IConvertible convertibleObj = obj as IConvertible; if (convertibleObj != null) { Type t = typeof(V);
switch (Type.GetTypeCode(t)) { case TypeCode.Boolean: return (V)(object)convertibleObj.ToBoolean(null); case TypeCode.Byte: return (V)(object)convertibleObj.ToByte(null); case TypeCode.Char: return (V)(object)convertibleObj.ToChar(null);
//......... default: //None of them, use the following default way.. break; } } return (V)(object)obj; } 不過這個方法看起來不但很丑、很麻煩,功能上還達不到VB版。所以建議您用到這種類型參數之間的轉換,就用VB封裝這一功能,然后做成dll供C#調用吧。
Public Function GenericCast(Of U, V)(ByVal obj As U) As V Try Return CType(DirectCast(obj, Object), V) Catch ex As InvalidCastException Return DirectCast( _ CompilerServices.Conversions.ChangeType(obj, GetType(V)), V) End Try End Function