简体   繁体   English

IEnumerable选项到IEnumerable选项

[英]IEnumerable of Options to Option of IEnumerable

I have a 3rd party method that get IEnumerable of T and evaluates it. 我有一个第三方方法,它获取IEnumerable of T并对其进行评估。 I would like to introduce Option with exceptional values (either) in my LINQ evaluation statements(select, where...) for the value that needs to get fed into the method. 我想在我的LINQ评估语句(选择,其中...)中为需要输入该方法的值引入具有异常值 (两个)的Option

For each T element I would like to have a method that can return the transformed element or an error (leaving it as deferred execution ) and If error is returned evaluation should stop there. 对于每个T元素,我希望有一个方法可以返回转换后的元素或错误(将其保留为延迟执行 ),如果返回错误,则评估应在此处停止。 (technically this can be achieved with throwing an exception, but this is exactly what im trying to avoid using Option) (从技术上讲,这可以通过引发异常来实现,但这正是我试图避免使用Option的原因)

I was wondering if this concept can be achieved with LINQ or more generally in C#? 我想知道这个概念是否可以使用LINQ或更广泛地用C#来实现?

If it can't be implemented this leads me to replace completely option in my code with throwing exceptions, because the same problem could show up for the client using my API with Options. 如果无法实现,则会导致我用抛出异常完全替换代码中的option,因为使用带有Options的API的客户端可能会出现相同的问题。

In summary this is what i am trying to achieve: 总而言之,这就是我要实现的目标:

This could be one possible mothod signture to implement: 这可能是实现的一种可能的方法:

public Option<IEnumerable<T>,TError> Sequence<T,TError>(IEnumerable<Option<T,TError>> options)

Which: 哪一个:

  • Should leave IEnumerable of T with deferred execution 应将IEnumerable保留为T并推迟执行

  • Should return first error found 应该返回发现的第一个错误

  • Should stop when error found 发现错误时应停止

** Final method needs IEnumerable of T which will eval it (it could be 3rd party method that i cannot access) and I don't want to evaluate the IEnumerable twice **最终方法需要IEnumerable的T,它将对其进行评估(它可能是我无法访问的第三方方法),并且我不想两次评估IEnumerable

After trying for a while to solve this problem, and having the feeling that exceptions should be able to be mimic with either monads, I posted a more conceptual version of this question . 尝试了一段时间以解决此问题,并感觉到两个单子都应该可以模仿例外之后,我发布了这个问题更具概念性的版本

Thanks, and based on mark's answer which as well confirmed my suspicion about "Either being isomorphic to C#/Java-style exceptions". 谢谢,并基于mark的回答,该回答也证实了我对“要么与C#/ Java风格的异常同构”的怀疑。

I was able to create the following implementation: 我能够创建以下实现:

public static class LinqEitherExtension
{
    public static IEnumerable<T> UntilException<T,TException>(
        this IEnumerable<Option<T,TException>> enumerable, 
        Action<TException> errorHandler
        )
    {
        return enumerable
            .TakeWhile(e =>
                           {
                               e.MatchNone(errorHandler);
                               return e.HasValue;
                           })
            .SelectMany(e => e.ToEnumerable());
    }
}


public class Program
{
    static void Main(string[] args)
    {
        var numbers = new List<int> {1, 2, 3, 4, 5};
        ThirdPartyFunction(numbers.Select(CheckNumbers).UntilException(Console.WriteLine));
        //returns: 
        //1     
        //2
        //3 is exceptional number.
    }

    public static Option<int,string> CheckNumbers(int number)
    {
        return number == 3
            ? Option.None<int, string>("3 is exceptional number.")
            : number.Some<int, string>();
    }

    //Cannot be accessed/altered
    public static void ThirdPartyFunction(IEnumerable<int> numbers)
    {
        foreach (var number in numbers) Console.WriteLine(number.ToString());
    }

}

Note: If the ThirdPartyFunction will continue to to do side effects (like Console.WriteLine) after consuming the enumerable, This will still leave a gap between exception throwing and using error as return type: 注意:如果在消耗枚举后ThirdPartyFunction继续产生副作用(例如Console.WriteLine),则在抛出异常和将错误用作返回类型之间仍然存在差距:

  • Throwing exceptions approach: Will not execute any more side effects as well. 抛出异常方法:也将不再执行任何副作用。
  • Eithers approach : Will let the ThirdPartyFunction to finish the execution, Client consuming the output of the function can ignore the return value, But any side effect happens inside will still execute. 任何一种方法:将让ThirdPartyFunction完成执行,使用该函数输出的Client可以忽略返回值,但是内部发生的任何副作用仍将执行。

For what I am after this will get the job done. 为此,我将完成工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM