Skip to content

[Question] Where(IsT0) followed by Select(AsT0) #208

@CrispyDrone

Description

@CrispyDrone

Is there a more concise alternative or elegant way to achieve the following?

// returns IEnumerable<OneOf<Success, MyError>>
var results = ImportFiles(files);

// I only care about the errors that are generated
var errors = results.Where(r => r.IsT1).Select(r => r.AsT1).ToList();

// do something with errors; other api expects a list
ShowErrorsToUser(errors);

I've considered this option, but it's not really any better, even slightly more wordy:

var results = ImportFiles(files);
var errors = new List<FileError>();
foreach (var r in importResults)
{
    r.Switch(_ => { }, errors.Add);
}

ShowErrorsToUser(errors);

I considered using OneOfBase and defining a manual conversion, but that doesn't work with Linq's OfType method, which uses the is operator. Linq's Cast brings me back to square one of needing a Where to filter out nulls.

edit: Cast apparently also doesn't support user-defined conversions.

    class CtxOrError : OneOfBase<Success, FileError>
    {
        protected CtxOrError(OneOf<Success, FileError> input) : base(input)
        {
        }

        public static implicit operator FileError?(CtxOrError input)
            => input.IsT1 ? input.AsT1 : null;
    }

I can just define an extension method like this:

public static class EnumerableExtensions
{
    public static IEnumerable<T0> FilterAsT0<T0, T1>(this IEnumerable<OneOf<T0, T1>> source)
    {
        return source.Where(s => s.IsT0).Select(s => s.AsT0);
    }

    public static IEnumerable<T1> FilterAsT1<T0, T1>(this IEnumerable<OneOf<T0, T1>> source)
    {
        return source.Where(s => s.IsT1).Select(s => s.AsT1);
    }
}

But wondering if there's a built-in way, or an extension method provided in one of the support libraries, thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions