C
Join ServerC#
help
Implementing IEnumerable<T>
RRotor2/15/2023
Hi all!
I'm trying to simplify a complex return type that I have to repeat in a lot of places
Although I'm pleased with how the type allows me to easily package and aggregate errors that I encounter without having to throw and catch them, the length of the type does no favours to the code's readability.
I sought to start to simplify the type a bit by contracting
down to
Which I tried to implement using the following code
Although the code compiles, once I started to update the code I use to generate an
Then I hit
Perhaps I'm looking at this problem from the wrong angle. Could somebody please set me right?
I'm trying to simplify a complex return type that I have to repeat in a lot of places
Result<IEnumerable<Result<TRow, Faults<TDataFault>>>, Faults<TMetadatFault>>
Although I'm pleased with how the type allows me to easily package and aggregate errors that I encounter without having to throw and catch them, the length of the type does no favours to the code's readability.
I sought to start to simplify the type a bit by contracting
IEnumerable<Result<TRow, Faults<TDataFault>>>
down to
IRowSeq<TRow, TDataFault>
Which I tried to implement using the following code
internal interface IRowSeq<TRow, TDataFault>
: IEnumerable<Result<TRow, Faults<TDataFault>>>
where TRow : IRowType
where TDataFault : Enum
{
public new IEnumerator<Result<TRow, Faults<TDataFault>>> GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() =>
this.GetEnumerator();
}
Although the code compiles, once I started to update the code I use to generate an
IEnumerable
private static IRowSeq<TRow, TDataFault> GetRows(ExcelData excelData)
{
ulong rowNumber = 1;
foreach (var row in excelData.Rows.Skip(1)) // By this point in the code the header has been confirmed
{
yield return ParseAndValidateCells(excelData, row, rowNumber);
rowNumber++;
}
}
Then I hit
csharp(CS1624)
- the body of (method) cannot be an iterator block because 'IRowSeq<TRow, TDataFault>' is not an iterator interface type
Perhaps I'm looking at this problem from the wrong angle. Could somebody please set me right?
TTvde12/15/2023
you can only use
yield
when your method returns an IEnumerable
(<T>
) or IAsyncEnumerable
(<T>
)TTvde12/15/2023
because it creates a class under the hood which implements just IEnumerable and IEnumerator
RRotor2/15/2023
It seems strange to me that it specifically needs to be
IEnumerable
when an interface implementing IEnumerable
should be functionally identical for the purposes of yield
TTvde12/15/2023
any other interface might contain additional methods that must be implemented, which the generated Enumerable can't
RRotor2/15/2023
Aha yes that makes sense
TTvde12/15/2023
there could possibly be a check that checks if the interface is ONLY an IEnumerable, then it could pass, but that was never added
RRotor2/15/2023
In that case do you have any suggestions for how I might start to wrap up this long return type without adding too much boilerplate code responsible for wrapping and unwrapping the data?
TTvde12/15/2023
Tthinker2272/15/2023
(
IEnumerator<T>
as well)RRotor2/15/2023
CSharp could really use some good type alias features
RRotor2/15/2023
Alright gave this one a go and I think it's a small enough crime that I'll risk the Unsafe cast and make sure it's covered properly with tests. Thanks very much for the solution