title: What is the equivalent syntax in VB.NET for "yield return"?
body: <p>Using the <a href="http://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29" rel="noreferrer">C#</a> code below, how would you write it in Visual Basic? What is it trying to say?</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Windows;
  using System.Windows.Media;
  using System.Windows.Media.Imaging;
  
  namespace Microsoft.LiveLabs.Pivot
  {
      /// &lt;summary&gt;
      ///     Tile Builder class
      /// &lt;/summary&gt;
      public static class TileBuilder
      {
          /// &lt;summary&gt;
          ///     Specifies which images are required in the images array used in CreateTile
          ///     according to the Morton fractal pattern used by Seadragon.
          /// &lt;/summary&gt;
          /// &lt;remarks&gt;
          ///     Usage of this and CreateTile are kind of tricky. Here's an example:
          ///     Say you have a results set that is a collection of items like so: { item1, item2, ..., item100 }
          ///     Since Seadragon expects the tiles to be laid out in a Morton pattern,
          ///     level 6 will look like the following:
          ///
          ///     --------------------------
          ///     |0   1   4   5  | 16  17...
          ///     |2   3   6   7  | 18  19
          ///     |8   9   12  13 | 24  25
          ///     |10  11  14  15 | 26  27
          ///     |-----------------------
          ///     |32  33  36  37 | 48  49
          ///     |34  35  38  39 | 50  51...
          ///     |.          .
          ///     |.          .
          ///      .          .
          ///
          ///      Each tile at level 6 is 4x4, so the dashes represent tile boundaries. Now, say
          ///      you want to build 0,0. You need the images on that tile. The ids 0, 1, 4, 5...
          ///      represent the ids in your result set, { item1, item2, ..., item100 }. Calling
          ///      this method tells you the ids to use for a given tile. You then must retrieve
          ///      the necessary images out the result set, and supply them in the order this
          ///      method gave you to CreateTile. This will result in a correctly built tile
          ///      that Seadragon can use.
          /// &lt;/remarks&gt;
          /// &lt;param name="imageCount"&gt;Number of images in the full set.&lt;/param&gt;
          /// &lt;param name="level"&gt;The level to which each image will be downsampled.&lt;/param&gt;
          /// &lt;param name="row"&gt;The row number which specifies what images to render.&lt;/param&gt;
          /// &lt;param name="column"&gt;The row number which specifies what images to render.&lt;/param&gt;
          /// &lt;param name="tileSize"&gt;The size of the tile to return.&lt;/param&gt;
          public static IEnumerable&lt;int&gt; GetTileIds(
            int imageCount,
            int level,
            int row,
            int column,
            int tileSize)
          {
              // Calculate upper-left hand corner of tile in image space (1 unit = 1 image)
              int levelSize = (int)Math.Pow(2, level);
              int imagePerSide = tileSize / levelSize;
              int xOffset = row * imagePerSide;
              int yOffset = column * imagePerSide;
  
              if (imagePerSide &lt;= 0)
              {
                  throw new ArgumentOutOfRangeException("Level is greater than the maximum depth allowed by the tile size, or the tile size is 0.");
              }
  
              // Loop through x and y in image space, starting at the upper-left
              // hand corner of the tile. Find all ids on the given tile.
              for (int x = 0; x &lt; imagePerSide; x++)
              {
                  for (int y = 0; y &lt; imagePerSide; y++)
                  {
                      int n = XYToMorton(x + xOffset, y + yOffset);
                      if (n &lt; imageCount)
                      {
                          yield return n;
                      }
                  }
              }
          }
  
          /// &lt;summary&gt;
          ///     Create a tile for a collection according to the Morton fractal
          ///     pattern used by Seadragon.
          /// &lt;/summary&gt;
          /// &lt;remarks&gt;
          ///     See GetTileIds for more information.
          /// &lt;/remarks&gt;
          /// &lt;param name="imageCount"&gt;The total number of images in the collection.&lt;/param&gt;
          /// &lt;param name="images"&gt;Jpeg images to render on this tile.
          ///     If this is null, a blank tile will be returned.
          ///     See GetTileIds remarks for more information.&lt;/param&gt;
          /// &lt;param name="level"&gt;The level to which each image will be downsampled.&lt;/param&gt;
          /// &lt;param name="row"&gt;The row number which specifies what images to render.&lt;/param&gt;
          /// &lt;param name="column"&gt;The row number which specifies what images to render.&lt;/param&gt;
          /// &lt;param name="tileSize"&gt;The size of the tile to return.&lt;/param&gt;
          /// &lt;param name="output"&gt;The stream to use to output the result.&lt;/param&gt;
          public static void CreateTile(
            int imageCount,
            IEnumerable&lt;ImageBag&gt; images,
            int level,
            int row,
            int column,
            int tileSize,
            string fileType,
            Stream output)
          {
              // Calculate upper-left hand corner of tile in image space (1 unit = 1 image).
              int levelSize = (int)Math.Pow(2, level);
              int imagePerSide = tileSize / levelSize;
              int xOffset = row * imagePerSide;
              int yOffset = column * imagePerSide;
  
              if (imagePerSide &lt;= 0)
              {
                  throw new ArgumentOutOfRangeException("Level is greater than the maximum depth allowed by the tile size, or the tile size is 0.");
              }
  
              if (output == null)
              {
                  throw new ArgumentNullException("The given output stream is null.");
              }
  
              // Create the tile.
              WriteableBitmap outputBitmap = new WriteableBitmap(
                tileSize,
                tileSize,
                96,
                96,
                PixelFormats.Bgr24,
                null);
  
              // If images is null, return a blank tile.
              if (images != null)
              {
                  // Loop through the tile in relative x and y image-space.
                  IEnumerator&lt;ImageBag&gt; imageEnumerator = images.GetEnumerator();
                  for (int x = 0; x &lt; imagePerSide; x++)
                  {
                      for (int y = 0; y &lt; imagePerSide; y++)
                      {
                          // Convert to Morton id-space from the absolute image-space (to get absolute, add offsets).
                          int n = XYToMorton(x + xOffset, y + yOffset);
                          if (n &lt; imageCount)
                          {
                              if (imageEnumerator.MoveNext())
                              {
                                  if (imageEnumerator.Current == null)
                                  {
                                      continue;
                                  }
  
                                  // Compute the pixel location
                                  int locX = levelSize * x;
                                  int locY = levelSize * y;
  
                                  int width = 0;
                                  int height = 0;
                                  imageEnumerator.Current.ImageSize(out width, out height);
                                  MemoryStream imageStream = new MemoryStream(imageEnumerator.Current.ImageData);
  
                                  // Determine the largest tile size to the nearest power of two for
                                  // this image: 2^ceil(lg max(width, height)).
                                  double maxTileSize = Math.Pow(2, Math.Ceiling(Math.Log(Math.Max(width, height), 2)));
  
                                  // Downsample to the correct size and decompress the image. The correct size
                                  // is total dimenion of the image * level size / max tile size required for
                                  // total width. Think of this as dividing the dimensions by two foreach
                                  // levels, starting at the max tile size, and going up to the current
                                  // tile size
                                  TransformedBitmap downsampledImage = JpegDecoder.DownsampleJpeg(
                                      imageStream,
                                      Math.Ceiling(width * levelSize / maxTileSize),
                                      Math.Ceiling(height * levelSize / maxTileSize));
  
                                  // Copy the pixels to a buffer and then write them to the
                                  // appropriate region on the output image.
                                  int stride = (downsampledImage.PixelWidth * downsampledImage.Format.BitsPerPixel + 7) / 8;
                                  byte[] buffer = new byte[stride * downsampledImage.PixelHeight];
                                  downsampledImage.CopyPixels(buffer, stride, 0);
  
                                  Int32Rect outputRect = new Int32Rect(locX, locY, downsampledImage.PixelWidth, downsampledImage.PixelHeight);
                                  outputBitmap.WritePixels(outputRect, buffer, stride, 0);
                              }
                              else
                              {
                                  // We should render the image, but we're done with our list.
                                  // So, exit both loops.
                                  x = imagePerSide;
                                  y = imagePerSide;
                              }
                          }
                          else
                          {
                              // Since n is monotonic wrt y, we know y has gone too far down, so
                              // we can reset it.
                              y = imagePerSide;
                          }
                      }
                  }
              }
  
              // Write the output
              BitmapFrame outputFrame = BitmapFrame.Create(outputBitmap);
              BitmapEncoder encoder = new JpegBitmapEncoder();
              encoder.Frames.Add(outputFrame);
              encoder.Save(output);
          }
  
          /// &lt;summary&gt;
          ///     Converts an x and y to a Morton number
          /// &lt;/summary&gt;
          /// &lt;param name="x"&gt;x location to convert.&lt;/param&gt;
          /// &lt;param name="y"&gt;y location to convert.&lt;/param&gt;
          /// &lt;returns&gt;Returns the morton number which corresponds to the
          ///          given x and y coordinates.&lt;/returns&gt;
          private static int XYToMorton(int x, int y)
          {
              const uint BITS_PER_BYTE = 8;
              const uint BIT_PAIRS = sizeof(int) * BITS_PER_BYTE / 2;
  
              int morton = 0;
              for (int i = 0; i &lt; BIT_PAIRS; i++)
              {
                  morton |= (x &amp; 1) &lt;&lt; (i * 2);
                  morton |= (y &amp; 1) &lt;&lt; ((i * 2) + 1);
                  x &gt;&gt;= 1;
                  y &gt;&gt;= 1;
              }
  
              return morton;
          }
      }
  }
  </code></pre>