match value with | :? list<#SomeType> as l -> l //Is it possible to match any list of a type derived from SomeType? | _ -> failwith "doesn't match"
5 Réponses :
Non, il n'est malheureusement pas possible de faire quelque chose comme ça - le CLR ne fournit aucune façon efficace de faire ce type de test de type. Voir Comment lancer un objet à une liste de type générique dans F # et F # et motif correspondant aux génériques dans une méthode non générique mettant en œuvre une interface pour quelques solutions (plutôt laides). P>
Comme déjà signalé, il n'ya aucun moyen de le faire directement (la correspondance des motifs ne peut connecter que des valeurs, mais elle ne peut pas lier de nouvelles variables de type). En plus de la solution de contournement (plus générale) par kvb em> Vous pouvez utiliser le fait que toutes les collections implémentent non générique ienumerable code>, afin que vous puissiez vérifier ce type:
match box value with
| :? System.Collections.IEnumerable as l when
// assumes that the actual type of 'l' is 'List<T>' or some other type
// with single generic type parameter (this is not fully correct, because
// it could be other type too, but we can ignore this for now)
typedefof<SomeType>.IsAssignableFrom
(value.GetType().GetGenericArguments().[0]) ->
l |> Seq.cast<SomeType>
| _ -> failwith "doesn't match"
J'ai plus tard eu besoin de quelque chose de similaire pour faire correspondre des cas paresseux. Voici ma solution, au cas où quelqu'un le trouve utile. Utilisation: P> match value with
| Lazy typ when typeof<SomeType>.IsAssignableFrom(typ) -> (value :?> Lazy<_>).Value
| _ -> failwith "not an instance of Lazy<#SomeType>"
pas le plus propre, mais efficace:
Non que je suppose que cela compte, mais pourquoi avez-vous besoin de faire correspondre une liste de type? Si la liste est homogène, vous pouvez simplement traiter l'élément de liste par élément et c'est bien. Si la liste est hétérogène, vous ne pouvez pas envisager la liste comme une unité logique. Quel est le problème que vous essayez de résoudre ici?
Je suppose que j'aurais dû utiliser mon code actuel. J'utilise juste la liste pour la simplicité. La question est de savoir comment faire une correspondance flexible sur les paramètres de type.