In C#, why can't an anonymous method contain a yield statement?

前端 未结 5 776
青春惊慌失措
青春惊慌失措 2020-11-30 19:23

I thought it would be nice to do something like this (with the lambda doing a yield return):

public IList Find(Expression

        
5条回答
  •  自闭症患者
    2020-11-30 20:00

    Maybe its just a syntax limitation. In Visual Basic .NET, which is very similar to C#, it is perfectly possible while awkward to write

    Sub Main()
        Console.Write("x: ")
        Dim x = CInt(Console.ReadLine())
        For Each elem In Iterator Function()
                             Dim i = x
                             Do
                                 Yield i
                                 i += 1
                                 x -= 1
                             Loop Until i = x + 20
                         End Function()
            Console.WriteLine($"{elem} to {x}")
        Next
        Console.ReadKey()
    End Sub
    

    Also note the parentheses ' here; the lambda function Iterator Function...End Function returns an IEnumerable(Of Integer) but is not such an object itself. It must be called to get that object.

    The converted code by [1] raises errors in C# 7.3 (CS0149):

    static void Main()
    {
        Console.Write("x: ");
        var x = System.Convert.ToInt32(Console.ReadLine());
        // ERROR: CS0149 - Method name expected 
        foreach (var elem in () =>
        {
            var i = x;
            do
            {
                yield return i;
                i += 1;
                x -= 1;
            }
            while (!i == x + 20);
        }())
            Console.WriteLine($"{elem} to {x}");
        Console.ReadKey();
    }
    

    I strongly disagree to the reason given in the other answers that it's difficult for the compiler to handle. The Iterator Function() you see in the VB.NET example is specifically created for lambda iterators.

    In VB, there is the Iterator keyword; it has no C# counterpart. IMHO, there is no real reason this is not a feature of C#.

    So if you really, really want anonymous iterator functions, currently use Visual Basic or (I haven't checked it) F#, as stated in a comment of Part #7 in @Thomas Levesque's answer (do Ctrl+F for F#).

提交回复
热议问题