C#-在匹配键上联接两个LanguageExt <Error,List <T >>

时间:2019-09-19 10:59:51

标签: c# linq monads language-ext

在下面的示例中,我有两组具有匹配键的对象。

class Stuff
{
    int Key1 { get; set; }
    ... other props
}

class OtherStuff
{
    int Key2 { get; set; }
    ... other props
}

我想将这些对象的两个列表作为一对对连接在一起。假设存在一个名为Error的类,它表示错误状态。我尝试通过以下方式进行操作;

Either<Error, List<Stuff>> eitherStuff = GetStuff();

Either<Error, List<OtherStuff>> eitherOtherStuff = GetOtherStuff();

Either<Error, List<object>> eitherCombined =
    from stuff in eitherStuff
    select stuff into s1
    from otherStuff in eitherOtherStuff
    select otherStuff into s2
    from s1item in s1
    join s2item in s2
    on s1item.Key1 equals s2item.Key2
    select new {s1item, s2item};

但这失败

  

名称“ s1”在当前上下文中不存在。

结合两个Either<Error, List<T>>的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

Either<Error, List<(Stuff, OtherStuff)>> eitherCombined =
                from stuff in eitherStuff
                from otherStuff in eitherOtherStuff
                select (from s1item in stuff
                        join s2item in otherStuff
                        on s1item.Key1 equals s2item.Key2
                        select (s1item, s2item)).ToList();

外部LINQ表达式结合了两个Either元素。内部LINQ表达式连接列表(如果两个都为“正确”)。

我将您的返回类型更改为元组以避免对象。您最初的示例将是

Either<Error, List<object>> eitherCombined =
                from stuff in eitherStuff
                from otherStuff in eitherOtherStuff
                select (from s1item in stuff
                        join s2item in otherStuff
                        on s1item.Key1 equals s2item.Key2
                        select new {s1item, s2item} as object).ToList();

您可以这样使用匿名类型(没有不安全的object):

var eitherCombined =
                from stuff in eitherStuff
                from otherStuff in eitherOtherStuff
                select (from s1item in stuff
                        join s2item in otherStuff
                        on s1item.Key1 equals s2item.Key2
                        select new {s1item, s2item}).ToList();

另一个提示:您可以使用LanguageExt不可变类型之一代替List ...