Search code examples
c#.netsystem.text.json

Why does JsonElement.ArrayEnumerator implement IEnumerable?


I realised that I can get an enumerator from ArrayEnumerator, which itself is already an IEnumerator Neither List, nor Array has this. I'm curious what's the reason for implementing IEnumerable on an IEnumerator ? I am not using GetEnumerator() calls, I'm aware of foreach, I'm curious about what kind of requirement or use case for an enumerator would lead to this design choice It was not considered necessary for the most commonly used array and list types, so why is it in place for the ArrayEnumerator type? Here's the linqpad code that demonstrates what I am talking about:

var myArr = new int[] {1,2,3};
var enumerator1 = myArr.GetEnumerator(); //no more .GetEnumerator()

var myLst = new List<int>();
myLst.Add(1); myLst.Add(2);
myLst.GetEnumerator(); //no more .GetEnumerator()

var jsonDoc = System.Text.Json.JsonDocument.Parse("[\"a\",\"b\",\"c\"]");
System.Text.Json.JsonElement.ArrayEnumerator arrEnum = jsonDoc.RootElement.EnumerateArray();
System.Text.Json.JsonElement.ArrayEnumerator arrEnum1 = arrEnum.GetEnumerator();

foreach (var el in arrEnum){
    el.Dump("0");
}

foreach(var el in arrEnum1){
    el.Dump("1");
}

Solution

  • This is based on the comment from @panagiotis-kanavos. Briefly: there is no design decision to use an IEnumerator<T> as an IEnumerable<T> The reason for ArrayEnumerator's GetEnumerator() returning both the expected IEnumerator<T> and an IEnumerable<T> is because it is returning itself specifically, i.e. the ArrayEnumerator type, which supports both interfaces. The type implements both interfaces to lessen the number of allocations.

    I personally suspect the reason to return the type itself rather than the interface is to signify the fact that the type implements both inferfaces, but I'm not sure about that one. Nonetheless, the answer to my question is that this is a consequence of a decision made for performance reasons, not related to reusing an IEnumerator<T> as an IEnumerable<T>