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