F# équivalent du C# typeof(IEnumerable<>)
J'ai un morceau de code où j'ai besoin de comprendre si un type donné, il met en œuvre IEnumerable<T>
(je n'aime pas à propos de le T)
J'ai essayé (t:System.Type
dans le cas où vous vous demandez)
let interfaces = t.GetInterfaces()
let enumerbale =
interfaces.Any(fun t ->
t.GetGenericTypeDefinition() = typeof<IEnumerable<>>
)
cependant qui ne compile pas (la compilation n'aime pas les <>). J'ai ensuite essayé
let interfaces = t.GetInterfaces()
let enumerbale =
interfaces.Any(fun t ->
t.GetGenericTypeDefinition() = typeof<IEnumerable<'a>>
)
mais un avertissement que " a est contrainte à l'obj. Je Ne veux pas savoir si IEnumerable<obj>
est mis en œuvre, mais IEnumerabl<>
.
Tout savoir de la solution et btw, n'hésitez pas à commenter le code ci-dessus.
Vous devez vous connecter pour publier un commentaire.
Cela devrait fonctionner:
MODIFIER
Comme Tomas notes, il n'y a rien de spécial à propos de la
_
générique ici; F# en déduit que le typeobj
est le plus général type applicables dans ce contexte, c'est donc le même que l'utilisation detypedefof<System.IEnumerable<obj>>
. Dans certains cas, la façon dont cela fonctionne peut être un peu d'un obstacle, si. Par exemple, si vous définissez une interfacetype I<'a when 'a :> I<'a>> = interface end
, alors vous ne pouvez pas utilisertypedefof<I<_>>
, parce queI<obj>
ne satisfait pas la contrainte générique et F# on ne peut pas en déduire un autre plus approprié. Cela peut se produire même sans récursive contraintes (par exemple,type I<'a when 'a : struct and 'a :> System.ICloneable> = interface end
. Ceci est en contraste à C#, s'approche, qui fonctionne parfaitement bien dans le cas analogue.De votre code lui-même, je pense que vous aurez envie de faire quelques autres changements, trop, comme s'assurer que l'interface est générique avant d'appeler
GetGenericTypeDefinition
. Voici comment allais-je écrire la fonction de test:Autant que je sache, F# n'a pas d'équivalent à C#'s
typeof(IEnumerable<>)
. C'est parce que, c'est une syntaxe spéciale prise en charge explicitement par C#. En F#,typeof
est une fonction normale et le type de l'argument doit être un type spécifié. Vous pouvez obtenir un type générique de définition par programmation comme ceci:Le problème avec ta solution avec
IEnumerable<'a>
est que le compilateur F# a encore besoin de trouver certains type de béton à utiliser (comme le type générique de la définition n'est pas d'un type valide). Si l'inférence de type en déduit que le paramètre de type n'est pas limité en aucune manière, il utilise par défaut le type, qui estobj
.MODIFIER je ne connaissais pas
typedefof<IEnumerable<_>>
, qui est très utile! De toute façon, remarque que le trait de soulignement n'ont pas de signification particulière ici - le type réel argument est encoreIEnumerable<obj>
, mais letypedefof
appels de fonctionGetGenericTypeDefinition
derrière la scène.Je m'en voudrais de ne pas souligner que cette question est l'une des nombreuses dont les réponses se trouvent dans
Ce que fait ce code C# ressembler en F#?