[Mono-list] yield

Bernhard Herzog schwimmlehrer at gmail.com
Thu Sep 15 16:34:25 EDT 2005


Well, ok. Thanks :)

> Right. But I would be surprised if that code is allowed because
> AFAÏK it is not possible to branch to inside a try block, right?

According to the Microsoft documentation it is ok to have yield in a try 
block if there is no catch clause:
<http://winfx.msdn.microsoft.com/library/en-us/dv_csref/html/1089194f-9e53-46a2-8642-53ccbe9d414d.asp>

I did a quick test. This is valid with csc. It is similar to having lock () 
{}

  try
  {
   for (int i = 0; i < 10; i++)
    yield return true;
  }
  finally
  {
  }


  lock (lockit)
  {
   for (int i = 0; i < 10; i++)
    yield return true;
  }

This is invalid:

  try
  {
   for (int i = 0; i < 10; i++)
    yield return true;
  }
  catch (Exception e)
  {
  }


Test.cs(38,5): error CS1626: Cannot yield a value in the body of a try block
        with a catch clause

Bernhard

----- Original Message ----- > > It's a bug in gmcs.
> >
> > However, using 'lock' and 'yield' together doesn't sound like a good
> > idea to me.  The standard doesn't specify anything about releasing and
> > re-acquiring the lock around a yield[1]: so, the lock is very
> > long-lived.
>
>
> I have filed a bug report.
>
> >From the Microsoft C# Programmers Reference:
> Unsafe blocks are not allowed
>
> My naive unterstanding of how yield works was that code until the loop is
> executed (i.e. the lock is aquired), then the code inside the foreach (the
> one that called the function containing yield) is called and finally the
> code after my loop is called (i.e. the lock is released).

Yes, that's an understandable assumption but it is not how it works.
The actual flow is a little more complicated. Every time the code hits
an 'yield' it leaves the method and sets the yield return argument as
the current item for the iteration. When the code needs to consume
another item the method is reexecuted starting from the line just
after the last executed yield statement (the compiler emits code to
branch to that point upon reentering the method). At least that's how
it works in boo and I'm (naively?) assuming the c# model would be
pretty much the same.

-- 
bamboo
http://blogs.codehaus.org/people/bamboo/
Got objects? http://www.db4o.com/ 



More information about the Mono-list mailing list