Note : Cette réponse est maintenant ancienne. Les blocs d'itérateurs ont depuis été ajoutés à VB.NET
C# traduit le mot-clé yield en une machine d'état au moment de la compilation. VB.NET n'a pas le mot-clé yield, mais il a son propre mécanisme pour intégrer en toute sécurité l'état dans une fonction qui n'est pas facilement disponible en C#.
Le C# static
est normalement traduit en Visual Basic à l'aide du mot-clé Shared
mot-clé, mais il y a deux endroits où les choses deviennent confuses. L'un d'eux est qu'une classe statique C# est en réalité un module en Visual Basic plutôt qu'une classe partagée (on aurait pu penser qu'ils vous laisseraient coder dans les deux cas en Visual Basic, mais non). L'autre est que VB.NET possède sa propre classe statique C#. Static
mot-clé. Cependant, Static
a une signification différente en VB.NET.
Vous utilisez le Static
en VB.NET pour déclarer une variable à l'intérieur d'une fonction, et lorsque vous le faites, la variable conserve son état entre les appels de fonction. C'est différent de la simple déclaration d'un membre de classe statique privé en C#, car un membre de fonction statique en VB.NET est garanti comme étant également thread-safe, dans la mesure où le compilateur le traduit pour utiliser la classe Monitor au moment de la compilation.
Alors pourquoi écrire tout ça ici ? Eh bien, il devrait être possible de construire un système générique réutilisable. Iterator<T>
(ou Iterator(Of T)
en VB.NET). Dans cette classe, vous implémenteriez la machine à états utilisée par C#, avec Yield()
y Break()
qui correspondent aux mots-clés C#. Vous pouvez alors utiliser une instance statique (au sens de VB.NET) dans une fonction afin qu'elle puisse, en fin de compte, faire à peu près le même travail que la méthode C# yield
dans à peu près la même quantité de code (sans tenir compte de l'implémentation de la classe elle-même, puisqu'elle serait réutilisable à l'infini).
Je ne me suis pas assez intéressé au Yield pour le tenter moi-même, mais debe être réalisable. Cela dit, c'est également loin d'être trivial, car Eric Lippert, membre de l'équipe C#, qualifie cette situation de " la transformation la plus compliquée du compilateur ."
Depuis que j'ai écrit la première version de ce document il y a plus d'un an, j'en suis venu à penser que ce n'est pas vraiment possible de manière significative avant la sortie de Visual Studio 2010, car il faudrait envoyer plusieurs lambdas à la classe Iterator. .NET 4 La prise en charge des lambdas multi-lignes par l'utilisateur.
15 votes
"VB.NET n'a pas ce mot-clé." - plus maintenant. Pour tous les googleurs qui trouvent cette page, consultez le cadre Microsoft Async. msdn.microsoft.com/fr/us/vstudio/gg316360 y msdn.microsoft.com/fr/us/vstudio/gg497937
0 votes
@mattmc3 : notez que cela nécessite 2012, et ne fonctionne pas dans VS.2010
0 votes
@mattmc3 : le framework Async (votre premier lien) semble être une solution plus lourde (et plus complexe) que Yield (votre deuxième lien) ? Non pas que cela ait de l'importance puisque Yield est apparu dans VB à la même époque. Je veux juste connaître les tenants et aboutissants des différentes approches. msdn.microsoft.com/fr/us/magazine/hh456402.aspx discute d'Async/Await. UTILISATION DE
await
est assez facile. Mais l'implémentation de l'autre côté, qui génère le flux d'objets, semble demander beaucoup plus de travail que de simplement dire "Yield".0 votes
Pour info, dans VS2010, j'ai pu utiliser Linq dans certaines situations, pour éviter de créer de grandes listes intermédiaires.
Where
ySelect
. Ex :Dim zsEnum As IEnumerable(Of Double) = (From p In points Where p.Y > 0 Select p.Z)
,For Each z As Double In zsEnum ...
. Parce que Linq crée un IEnumerable plutôt qu'une liste concrète, ce qui précède ne consomme pas de mémoire supplémentaire significative. Important pour les listes volumineuses, dans un processus .Net 3.5 32 bits, pour éviter de fragmenter davantage la mémoire.0 votes
Cette réponse plus récente montre l'utilisation de la fonction VB
Yield value
(à l'intérieur d'unIterator Function
déclaration), qui a été ajouté des années après que cette question ait été posée.