none
如何取得泛型型別? RRS feed

  • 問題

  • Dear all

    小弟在開發過程中有一個泛型的疑問,

    1 Public Function ReturnObject(Of T)(thisParam As StringAs T 
    2    Dim _Item As T = Nothing  
    3    '程式處理,期間 _Item 會被指派參考到某個 T 型別的執行個體 
    4    Return _Item 
    5 End Function  

    如上述程式碼,小弟發現只有在 _Item 被參考到某個 T 型別的執行個體後,
    才能使用 Type.GetType 的方式取得 T 型別實際的型別 (例如 Integer、String ...),
    在指派前取回的會是 nothing,
    由於目前這個 method 內部參考的 T 型別執行個體可能有一些問題,
    因此需要在這個 method 內部先知道有問題的 T 實際上是哪一種型別,
    想請教諸位先進,要如何才能在指派 _Item 前取得 T 實際上表示的型別?
    2009年3月4日 上午 02:22

解答

所有回覆

  • HI,

    指派之前只能使用T做為型態, 如果在指派之前要知道變數的真正型態, 已經違背泛型的本質了
    2009年3月4日 上午 04:24
  • 哪你再註解的地方先做 Item.GetType ,確定是你要的型別再指給 _Item ?

    2009年3月4日 下午 01:01
  • Dear tihs大

    小弟對泛型有些疑感不解的地方,
    當內外部的程式在呼叫 ReturnOubject 方法時,
    ex.

    1 Dim _TempString As DateTime = ReturnObject(Of DateTime)("test string"

    不是已經使用 (Of xxx) 去宣告它的型別了嗎?
    那麼在 ReturnObject 方法的內部還是沒辨法在執行期間取得外部指定的型別嗎?



    Dear 心冷大

    不好意思,小弟再補充詳細一些,
    1 Public Function ReturnObject(Of T)(thisParam As StringAs T   
    2     Dim _Item As T = Nothing    
    3   
    4     Dim _Type As Type = _Item.GetType  
    5   
    6     '程式處理,期間會將某個被序列化後存放在記憶體的物件反序列化回原始物件,  
    7     '並將反序列化回來的物件指定給 _Item(如下行程式碼)  
    8     _Item = Deserialize(thisParam) 
    9   
    10     Return _Item   
    11 End Function    

    因為 ReturnObject 是一支公用函式,
    現在不知道是哪一支程式在處理資料時沒有處理好,
    以致於執行行號 8 時,會發生傳進來的 thisParam 變數是空字串,
    而導致反序列化時發生「未設定物件參考」...等問題,

    因為會呼叫 ReturnObject 的程式都是我們內部一些有自訂型別的程式,
    所以如果能知道泛型被指派的實際型別為何,
    那麼是哪一支程式的哪幾行程式碼出問題答案就呼之欲出了,
    否則的話就只好含淚到那一堆有呼叫 ReturnObject 的程式中一支一支去加 Log 了。


    2009年3月9日 上午 01:56
  • HI,

    在製作ReturnObject功能時就是使用T當做型態, 因為ReturnObject被使用時可能會指定不同的型態, 所以程式製作時就是用T當型態
    2009年3月9日 上午 02:37
  • Dear tihs 大

    速滴速滴,
    所以小弟嘗試直接去取宣告為 T 的 _Item 的型別 (呼叫 _Item.GetType),
    但是沒想到傳回來的是 Nothing,
    所以在讓 _Item 參考到某個物件前,
    似乎就沒辨法使用一般的 Type 類別去取得泛型的型別,
    不知道您是否還可以再提供我其它參考資訊?
    2009年3月9日 上午 03:28
  • 如果這是你的程式碼:
    _Item = Deserialize(thisParam)

    那你應該是自定類別,又或者 Deserialize(String) 是你自己寫的方法?從這片段的程式碼不確定你呼叫的是哪個 Deserialize ,你的類別宣告是啥?

    如果只是不想錯誤,那直接:

    Try 
       _Item = Deserialize(thisParam)  
    Catch 
       _Item = Nothing 
    End Try 

    很多時候根本不需要知道這個東西的型別,直接錯誤處理常式帶過去就可以了。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    2009年3月9日 上午 03:49
  • Dear 心冷大

    Deserialize(thisParam) 是內部自己寫的一個方法,
    主要是將傳進去的字串先轉成位元組陣列,
    再使用 Binary.BinaryFormatter 方法還原回原始的物件,

    目前程式上有做錯誤控制,
    但是使用者操作時三不五時就會被跳轉到資料結果異常的頁面,

    最近很認真的在思考下班的時候要不要從後門走(雖然現在還不知道是誰的哪一支程式有問題),
    免得被使用者堵到,哈。
    2009年3月9日 上午 04:04
  • 看這個例子 :
        Dim d As DateTime = Nothing
        Debug.Print(d.GetType.ToString)
        Dim s As String = Nothing
        Debug.Print(s.GetType.ToString)
    參考型別沒有執行個體時 無法使用GetType
    所以要想辦法給個執行個體

    試試這樣
        Public Function ReturnObject(Of T)(ByVal thisParam As String) As T
            Dim ItemType As New clsGetType(Of T)
            Debug.Print(ItemType.ToString)
            ' ...
            Dim _Item As T
            Return _Item
        End Function
        Public Class clsGetType(Of T)
            '
        End Class

    2009年3月9日 上午 05:12
  • 不是很看得懂你的說明,你好像是要這個?

    Debug.Print(GetType(T).ToString) 

    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    • 已標示為解答 Johnny Fang 2009年3月9日 上午 07:37
    2009年3月9日 上午 07:23
  • 心冷熱情熄 表示:

    不是很看得懂你的說明,你好像是要這個?

    Debug.Print(GetType(T).ToString) 

    論壇是網友平等互助 保證解答請至 微軟技術支援服務


    Dear 心冷大

    就是這個啦 !!
    唉呀呀,原來 T 可以用 GetType 直接抓,
    之前太執著在 "用物件取得型別" 這件事情上了。


    感謝每一位回覆的先進



    2009年3月9日 上午 07:41