2010-10-19 6 views
6

J'essaie de déterminer si un obj retourné par un appel est d'un certain type. Voici mon code:f # comparaison de type générique

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

et une méthode qui a une portée MyType ...

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

Comment puis-je savoir si un est de type MyType?

+0

Hmmm, vérification du type d'exécution? Savez-vous quels types retourne votre méthode? Si oui, peut-être vous pouvez envelopper le type dans une union de type-safe et utiliser la correspondance de modèle à la place, peut-être vos types dans cette fonction peuvent exposer une interface commune? Il y a beaucoup de choses que vous pouvez faire pour éviter une vérification de type à l'exécution. – Juliet

+0

Que faire si vous ne savez pas ce que les types retournent sont? Voir mon post ci-dessous AS T1 > est différent thean T1 > et si vous vous souciez seulement de l'objet étant de T1 indépendamment des autres spécificités? – akaphenom

Répondre

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

Si vous vous souciez juste un MyType<X> pour une X inconnue,

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

Il semble que j'ai un autre problème. Il semble que someFunThatReturnsObj() retourne 'U. En utilisant votre première méthode suggérée, j'obtiens: "Ce test de type coercition ou type d'exécution de type 'U à MyType implique un type indéterminé basé sur des informations antérieures à ce point de programme. Les tests de type Runtime ne sont pas autorisés sur certains types. nécessaire." – PhilBrown

+1

Appelez simplement «boîte» d'abord, puis. "match box a avec ..." – Brian

+0

Je ne suis pas sûr de ce que vous entendez par «boîte» Brian? – PhilBrown

1

Je ne pense pas que ce soit aussi simple que cela (rappelez-vous que je suis f # naïf) envisager le scénario follwoing où

1) nous utilisons des génériques sur plusieurs types 2) nous n'avons pas les informations de type pour un objet, donc il arrive dans une fonction comme type obj, comme dans certaines des bibliothèques .NET datacontract/serialization

que nous avons retravaillé ma proposition d'utiliser la réflexion:

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 

On dirait qu'il devrait y avoir beaucoup plus naturel de le faire ...

+0

C'est génial pour déterminer si les résultats tombent dans ma catégorie souhaitée SomeType >. Le problème auquel je suis toujours confronté est la distribution et l'utilisation des résultats en tant que SomeType >. J'ai le contrôle sur tout ce que T pourrait être. Quelqu'un peut-il suggérer une façon de le faire peut-être en utilisant une interface commune pour tous les objets que T pourrait être? Peut-être une superclasse commune? – PhilBrown

Questions connexes