2010-10-19 146 views
6

我想弄清楚,如果從調用返回的obj是某種類型。這裏是我的代碼:f#泛型類型比較

type MyType<'T>= 
    val mutable myArr : array 
    val mutable id : int 
    val mutable value : 'T 

,並在具有範圍MyType的一些方法...

let a = someFunThatReturnsObj() // a could be of type MyType 

我如何找出如果A爲MyType的嗎?

+0

嗯,運行時類型檢查?你知道你的方法返回什麼類型嗎?如果是這樣,也許你可以將類型封裝在類型安全的聯合中,並使用模式匹配來代替,也許你的類型可以暴露一個通用接口?有很多事情可以做,以避免運行時類型檢查。 – Juliet 2010-10-19 20:39:46

+0

如果你不知道返回的類型是什麼?看到我的帖子下面的AS T1 > is the different T1an >如果你只關心T1的對象而不管其他細節如何? – akaphenom 2010-10-20 18:58:01

回答

5
match a with 
| :? MyType<int> as mt -> // it's a MyType<int>, use 'mt' 
| _ -> // it's not 

如果你關心只是一個MyType<X>一些未知的X,然後

let t = a.GetType() 
if t.IsGenericType && t.GetGenericTypeDefinition() = typedefof<MyType<int>> then 
    // it is 
+0

它看起來像我有另一個問題。看起來someFunThatReturnsObj()返回'U.使用你的第一個建議的方法,我得到:「從'U到MyType '這種運行時強制或類型測試涉及基於此程序點之前的信息的不確定類型,某些類型不允許運行時類型測試。需要「。 – PhilBrown 2010-10-19 20:32:42

+1

然後,只需先調用'box'。 「火柴盒與...」 – Brian 2010-10-19 21:39:33

+0

我不確定你的意思是'box'Brian? – PhilBrown 2010-10-20 12:38:56

1

我不認爲這是一個簡單的(記得我是F#幼稚)考慮follwoing場景

1)我們在多種類型上使用泛型 2)我們沒有一個對象的類型信息,所以它作爲類型obj進入函數,就像在一些.NET數據合同/序列化庫中一樣

我返工我的建議,使用反射:

type SomeType<'A> = { 
     item : 'A 
    } 


type AnotherType<'A> = { 
    someList : 'A list 
} 

let test() = 

    let getIt() : obj = 
     let results : SomeType<AnotherType<int>> = { item = { someList = [1;2;3] }} 
     upcast results 

    let doSomething (results : obj) = 
     let resultsType = results.GetType() 
     if resultsType.GetGenericTypeDefinition() = typedefof<SomeType<_>> then 
      let method = resultsType.GetMethod("get_item") 
      if method <> null then 
       let arr = method.Invoke(results, [||]) 
       if arr.GetType().GetGenericTypeDefinition() = typedefof<AnotherType<_>> then 
        printfn "match" 

    getIt() |> doSomething 

好像應該是這樣做的更自然的方式...

+0

這對判斷結果是否屬於我所需的SomeType >類別很有用。我仍然面臨的問題是將結果作爲SomeType >進行投射和使用。我可以控制一切'T可能。任何人都可以提出一種方法來做到這一點,也許通過使用所有對象的通用接口'T可能是?也許是一個普通的超類? – PhilBrown 2010-10-21 14:00:49