A way to autogenerate struct enumerators #125358
Replies: 2 comments 4 replies
-
|
Starting from recent versions, struct enumerators are less impactful. Given the following example: public static int Sum(MyClass c)
{
int sum = 0;
foreach (int i in c)
sum += i;
return sum;
}
public sealed class MyClass(int[] arr) : IEnumerable<int>
{
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public IEnumerator<int> GetEnumerator() => new Enumerator(arr);
public sealed class Enumerator(int[] arr) : IEnumerator<int>
{
private int index = -1;
public int Current => arr[index];
object IEnumerator.Current => Current;
public bool MoveNext() => ++index < arr.Length;
public void Reset() => index = -1;
public void Dispose() { }
}
}For such simple case, since the classes are ; Method CSPlayground.Program:Sum(CSPlayground.MyClass):int (FullOpts)
G_M000_IG01: ;; offset=0x0000
push rbp
sub rsp, 32
lea rbp, [rsp+0x20]
G_M000_IG02: ;; offset=0x000A
xor eax, eax
mov rcx, gword ptr [rcx+0x08]
mov edx, 0xFFFFFFFF
mov r8d, dword ptr [rcx+0x08]
jmp SHORT G_M000_IG04
align [5 bytes for IG03]
G_M000_IG03: ;; offset=0x0020
cmp edx, r8d
jae SHORT G_M000_IG06
add eax, dword ptr [rcx+4*rdx+0x10]
G_M000_IG04: ;; offset=0x0029
inc edx
cmp r8d, edx
jg SHORT G_M000_IG03
G_M000_IG05: ;; offset=0x0030
add rsp, 32
pop rbp
ret
G_M000_IG06: ;; offset=0x0036
call CORINFO_HELP_RNGCHKFAIL
int3
; Total bytes of code: 60However, for
This would require quite different behaviour. |
Beta Was this translation helpful? Give feedback.
-
|
Please take a look at this post from the csharplang repository. There is a NuGet package that does exactly what you want! After installing the package, the syntax to use the feature is very simple: You just need to declare a public struct MyIterator : IEnumerator<int>
{
public static MyIterator Create()
{
yield return 1;
yield return 2;
yield return 3;
}
}More details can be found in the post I mentioned. When compiling your code with that package installed, the compiler-generated state machine will be changed to a |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
A recurrent pain point I often find when implementing collections is with writing
structenumerators for them.When implementing a collection's
GetEnumerator()method, I return a custom enumerator implemented as astruct, similarly toList<T>.Enumerator. This benefits me with an allocationless enumerator, but at the cost of me having to write more code and more unit tests. Most of that code is boilerplate, thus I often find myself thinking "If this could be automated somehow...". That's why I opened this discussion.Honestly, this is more to raise the idea in the air, so it can be evolved, than a concrete idea by itself. Because I'm not fully aware of every technical constraint each solution could introduce, I'm unable to give you an ellaborate idea.
Ideally, I wish I could just have a way of using the
yieldkeyword in theGetEnumerator()method, and maybe mark the method with some attribute or return some special type, and then have astructenumerator generated for me automatically. But I'm not sure if this would be feasible or have some drawbacks, given the nature ofstructs.I also have no idea how common this pain point is for other devs. To me, it is a bit of an annoyance, given that I frequently need to write custom collections specialized to my domains, and I really want to get the benefit of
structbased enumerators, specially in heavy-use enumerators.Finally, I'm also not 100% sure if this is already possible and if I just missed some .NET news at some point. If it is, I'm probably sounding somewhat dumb.
And, I hope this is the right repo to post this in, as there are several .NET related repos. Please forgive me if it is not.
Anyway, I'm happy to share with you this little thing that I wish could be improved.
Beta Was this translation helpful? Give feedback.
All reactions