国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

.NET泛型技巧之類型參數之間的轉換

2024-07-10 13:11:57
字體:
來源:轉載
供稿:網友
  首先我要介紹的技巧是如何提供類型參數之間的轉換。我們知道,.net泛型將每個類型參數理解為一個獨立的類型。如果不通過約束指定,編譯器不會對類型參數所代表的類型做任何假設。也就是說,如果在某個上下文中有兩個不同的類型參數u和v,編譯器不會知道運行時他們代表的真實類型能否進行類型轉換,因此會拒絕編譯如下代碼:

public function genericcast(of u, v)(byval obj as u) as v
 return ctype(obj, v)
end function


  除非我們加以約束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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 尉氏县| 九江县| 喜德县| 红原县| 株洲市| 衢州市| 乐陵市| 山西省| 双峰县| 温泉县| 三河市| 林州市| 绥江县| 磐石市| 卢龙县| 红桥区| 湘乡市| 新疆| 水城县| 泸西县| 沙河市| 华阴市| 河间市| 资中县| 临西县| 二连浩特市| 丹江口市| 左权县| 金溪县| 崇义县| 民权县| 肥城市| 景洪市| 荣昌县| 来安县| 阜城县| 东光县| 西华县| 双牌县| 会东县| 大冶市|