kjm00king / sharpkit

Automatically exported from code.google.com/p/sharpkit
0 stars 0 forks source link

foreach over object that implements IEnumerable<T> #292

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
There seems to be a conversion issue when you try to iterate over a container 
implementing IEnumerable

        [JsType(JsMode.Clr, Filename = "res/Default.js")]
        public class IntContainer : IEnumerable<int>
        {
            public IEnumerator<int> GetEnumerator()
            {
                yield return 1;
                yield return 7;
                yield return 8;
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }

            public IEnumerable<int> GetVals()
            {
                yield return 9;
                yield return 4;
                yield return 5;
            }
        }

Then in usage

            var container = new IntContainer();

            foreach (var val in container.GetVals())
            {
                new jQuery("body").append(val + "<br/>");
            }

            foreach (var val in container)
            {
                new jQuery("body").append(val + "<br/>");
            }

The first iteration works correctly but the second fails

    var $it1 = container.GetVals().GetEnumerator();
    while ($it1.MoveNext())
    {
        var val = $it1.get_Current();
        $("body").append(val + "<br/>");
    }
    var $it2 = container.GetEnumerator();
    while ($it2.MoveNext())
    {
        var val = $it2.get_Current();
        $("body").append(val + "<br/>");
    }

which result in an error:

Unhandled exception at line 27, column 12 in 
http://localhost:18072/res/Default.js
0x800a01b6 - JavaScript runtime error: Object doesn't support property or 
method 'MoveNext'

If I manually hack the JavaScript to put in the extra GetEnumerator() then it 
works e.g.

    var $it1 = container.GetVals().GetEnumerator();
    while ($it1.MoveNext())
    {
        var val = $it1.get_Current();
        $("body").append(val + "<br/>");
    }
    var $it2 = container.GetEnumerator().GetEnumerator();
    while ($it2.MoveNext())
    {
        var val = $it2.get_Current();
        $("body").append(val + "<br/>");
    }

/*Generated by SharpKit 5 v5.01.0000*/

Original issue reported on code.google.com by co...@gravill.com on 3 May 2013 at 1:58

GoogleCodeExporter commented 8 years ago
Heehee, nice one...
You're right, it seems that it's possible to 'yield' when returning IEnumerator 
as well (not just IEnumerable), I've modified the compiler to detect the return 
type of the method, and to add the GetEnumerator() within the method body.

Original comment by DanelK...@gmail.com on 3 May 2013 at 4:02