2010-10-19 11 views
6

Próbuję dowiedzieć się, czy obiekt zwracany z połączenia jest określonego typu. Tu jest mój kodu:f # ogólne porównanie typów

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

iw jakiś sposób, który ma MyType w zakresie ...

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

Jak mogę dowiedzieć się, czy jest typu MyType?

+0

Hmmm, sprawdzanie typu run-time? Czy wiesz, jakie typy zwraca twoja metoda? Jeśli tak, to może możesz zawinąć ten typ w bezpieczne dla rodzaju połączenie i zamiast tego użyć dopasowywania wzorca, może twoje typy w tej funkcji mogą ujawnić wspólny interfejs? Istnieje wiele rzeczy, które możesz zrobić, aby uniknąć sprawdzania typu w czasie wykonywania. – Juliet

+0

Co zrobić, jeśli nie wiesz, co zwracają typy? Zobacz mój wpis poniżej AS T1 > jest inny thean T1 > co, jeśli zależy ci tylko na obiekcie będącym T1, bez względu na inne szczegóły? – akaphenom

Odpowiedz

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

Jeśli zależy Ci tylko MyType<X> jakiegoś nieznanego X, następnie

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

Wygląda na to, że mam inny problem. Wydaje się, że someFunThatReturnsObj() zwraca "U. Za pomocą pierwszej sugerowanej metody otrzymuję: "Ta metoda przymusu lub test typu z typu" U "do MyType dotyczy typu nieokreślonego na podstawie informacji przed tym punktem programu Testy typu uruchomieniowego są niedozwolone w niektórych typach. potrzebne." – PhilBrown

+1

Najpierw wywołaj "pudełko", a następnie. "Dopasuj pudełko z ..." – Brian

+0

Nie jestem pewien, co masz na myśli przez "pudełko" Briana? – PhilBrown

1

I nie sądzę, że to jest takie proste (należy pamiętać, jestem f # naiwny) rozważyć scenariusz follwoing gdzie

1) używamy generycznych na wielu typach 2) nie mamy informacji o typie obiektu, więc przychodzi on do funkcji typu obj, jak w niektórych bibliotekach .NET datacontract/serialization

I przerobione moją propozycję wykorzystania refleksji:

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 

Wydaje się, że powinien być bardziej naturalny sposób to zrobić ...

+0

Jest to przydatne do sprawdzenia, czy wyniki mieszczą się w wybranej kategorii SomeType >. Problem, który wciąż napotykam, polega na rzutowaniu i wykorzystywaniu wyników jako SomeType >. Mam kontrolę nad wszystkim, co może być. Czy ktokolwiek może sugerować sposób na to, wykorzystując wspólny interfejs dla wszystkich obiektów? Być może powszechna nadklasa? – PhilBrown