The .NET Compiler Platform ("Roslyn") provides open-source C# and Visual Basic compilers with rich code analysis APIs.
davidwengier on main
[EnC] Allow deleting method (#6… (compare)
dotnet-bot on main-to-main-vs-deps
Avoid intermediary array alloca… Simplify Merge remote-tracking branch 'u… and 4 more (compare)
await
instead of .Result
public static IEnumerator GetEnumerator(this System.ValueTuple<int, int, int> range)
{
int start = range.Item1;
int end = range.Item2;
int step = range.Item3;
if (step > 0)
for (int i = start; i <= end; i += step)
yield return i;
else
for (int i = start; i >= end; i += step)
yield return i;
}
foreach (int i in (-10, 10, 3))
Console.WriteLine(i);
Sub Main(args As String())
For Each i In (1, 10, 2).GetEnumerator()
Console.WriteLine(i)
Next
Imports System.Runtime.CompilerServices
Public Module Tools
<Extension>
Public Iterator Function GetEnumerator(range As ValueTuple(Of Integer, Integer, Integer)) As IEnumerable
Dim start = range.Item1
Dim [end] = range.Item2
Dim [step] = range.Item3
If ([step] > 0) Then
For i = start To [end] Step [step]
Yield i
Next
Else
For i = start To [end] Step [step]
Yield i
Next
End If
End Function
End Module
(1, 10, 2).GetEnumerator()
expression works, but (1, 10, 2)
doesn't!
foreach
binds. There's nothing special about the GetEnumerator
method. Just C# recognizes certain patterns when lowering foreach
and VB a different set.
[StandardModule]
public sealed class Tools
{
[IteratorStateMachine(typeof(VB$StateMachine_0_GetEnumerator))]
public static IEnumerable GetEnumerator(this (int, int, int) range)
{
VB$StateMachine_0_GetEnumerator vB$StateMachine_0_GetEnumerator = new VB$StateMachine_0_GetEnumerator(-2);
vB$StateMachine_0_GetEnumerator.$P_range = range;
return vB$StateMachine_0_GetEnumerator;
}
}
@VBAndCs I don't understand what you're saying by "Seems that vb for each was able to consume C# getEnemurator b4 it was added to C#"
Try it on yout machine. The getenumerator extension method works in vb when it is written in C# but doesn't work when it is written in VB! For Each
in vb doesn what foreach in c# does in this matter, but seems the difference is in the generated state machine in both languages, or the way that Yield is implemented in both. Maybe it is a different attribute sued or a missing one. Seems something that can be fixed in vb to have the same functionality as c#.
(int, int, int)
, but you're calling it on (int, int)
just above. Those are different types
IEnumerable
and IEnumerator
.
using System;
using System.Collections;
using System.Runtime.CompilerServices;
foreach (int i in 20..10)
Console.WriteLine(i);
foreach (int i in (10, -10))
Console.WriteLine(i);
foreach (int i in (-10, 10, 3))
Console.WriteLine(i);
public static class Extensions
{
public static IEnumerator GetEnumerator(this System.Range range)
{
int start = range.Start.Value;
int end = range.End.Value;
if (end > start)
for (int i = start; i <= end; i++)
yield return i;
else
for (int i = start; i >= end; i--)
yield return i;
}
public static IEnumerator GetEnumerator(this System.ValueTuple<int, int> range)
{
int start = range.Item1;
int end = range.Item2;
if (end > start)
for (int i = start; i <= end; i++)
yield return i;
else
for (int i = start; i >= end; i--)
yield return i;
}
public static IEnumerator GetEnumerator(this System.ValueTuple<int, int, int> range)
{
int start = range.Item1;
int end = range.Item2;
int step = range.Item3;
if (step > 0)
for (int i = start; i <= end; i+=step)
yield return i;
else
for (int i = start; i >= end; i += step)
yield return i;
}
}