当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > .NET泛型技巧之类型参数之间的转换

ASP.NET
AspNetPager与Socut.Data使用方法
asp.net UpdaeProgress的简单用法
asp.net ajaxControlToolkit ValidatorCalloutExtender的简单用法
asp.net 简易生成注册码(数字+大小写字母)
asp.net中利用ashx实现图片防盗链代码
ASP.NET程序中常用代码汇总
ASP.NET 2.0/3.5中直接操作Gridview控件插入新记录
ASP.NET Ajax级联DropDownList实现代码
ASP.NET 2.0写无限级下拉菜单
asp.net Web Services上传和下载文件(完整代码)
asp.net DataGrid控件中弹出详细信息窗口
Asp.NET 多层登陆实现代码
利用Asp.Net回调机制实现进度条
ASP.NET Ref和Out关键字区别分析
Javascript调用Webservice的多种方法
.Net下的签名与混淆图文分析
.Net Compact Framework开发小技巧 推荐
.Net连接Oracle数据库的实现代码
js获取.aspx页面里面的服务器控件和.ascx中的服务器控件值
asp.net下 jquery jason 高效传输数据

ASP.NET 中的 .NET泛型技巧之类型参数之间的转换


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 207 ::
收藏到网摘: n/a

首先我要介绍的技巧是如何提供类型参数之间的转换。我们知道,.NET泛型将每个类型参数理解为一个独立的类型。如果不通过约束指定,编译器不会对类型参数所代表的类型做任何假设。也就是说,如果在某个上下文中有两个不同的类型参数U和V,编译器不会知道运行时他们代表的真实类型能否进行类型转换,因此会拒绝编译如下代码:

除非我们加以约束U是V的子类。这显然是为了类型安全做出的考虑,因为.NET这种跨程序集的泛型无法在编译时做出足够的检查来确保类型安全。但是限制了这种操作,就妨碍了我们做事,很多代码因此写不出来。于是,我们可以利用.NET所有类型的基类Object来绕过这一限制:

Return DirectCast(DirectCast(obj, Object), V)

VB的DirectCast运算符在泛型的类型参数上作用与C#的括号运算符相同。也就是说,这段代码用C#写起来是这样:

return (V)(object)obj;
这样,即使不约束U和V之间的关系,这段代码也能编译了。但是他的功能却不能令我们满意。这样写出的类型转换实际上还是仅当U是V本身或其子类的时候才能转换成功。而其他一切情况都会转换失败。不管U和V的运行时类型之间是否定义有其他类型转换规则。这显然不合我们意愿,我们希望int与double之间的转换等语言内置的类型转换都能够自动进行,否则就和约束没什么两样了。对VB用户来说有一个极为简单的解决方案——把第二次DirectCast变成CType:

以下为引用的内容:

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运行库的转换函数,该函数在运行期间对泛型类型参数的真实类型做了检查。而且这个过程的性能完全可以接受。

现在VB的用户已经轻松享受这一功能了。但是C#的事情还没完,因为C#没有如此智能的类型转换运算符,因此就需要手工实现VB运行库所代办的那些任务。其实就是利用了一下IConvertible:

以下为引用的内容:

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#调用吧。

经过研究发现Convert.ChangeType方法已经封装了IConvertible判断的那些代码,因此C#版可采用这种写法:

以下为引用的内容:

static V GenericCast<U, V>(U obj)
{
 return (V)Convert.ChangeType(obj, typeof(V));
}

不过它仍然没有VB版的CType功能丰富。此外我还发现了VB运行库的ChangeType还有支持用户自定义类型转换运算符的功能。所以终极版本如下:

以下为引用的内容:

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