代码之家  ›  专栏  ›  技术社区  ›  Avrohom Yisroel

LanguageExt-在返回TryAsync<Unit>的方法上尝试匹配时出错

  •  0
  • Avrohom Yisroel  · 技术社区  · 2 年前

    我在库中使用的方法返回 TryAsync<Unit> (愚蠢愚蠢的实现来显示签名)。。。

    public TryAsync<Unit> DoLibraryStuffAsync() =>
      TryAsync(unit);
    

    我想打这个电话,然后返回 Task<Either<string, Unit>> ,其中 string 将包含错误消息。我已经做到了。。。

    private async Task<Either<string, Unit>> DoMyStuffAsync() =>
      (await DoLibraryStuffAsync())
        .Match(_ => unit,
          ex => $"Ex: {ex.Message}");
    

    但是,这会在中的两个分支上都出现编译器错误 Match ...

    只有赋值、调用、递增、递减、等待和新对象表达式才能用作语句

    悬停在上面 火柴 ,我可以看出编译器已经处理了需要 Func s、 所以我希望能够返回 一串 或 unit ...

    enter image description here

    有人能解释我做错了什么,以及我是如何解决的吗?

    2 回复  |  直到 2 年前
        1
  •  1
  •   DreamingOfSleep    2 年前

    虽然我不能对这个问题给出完整的解释(因为我自己也不完全理解!),但我可以建议如何解决它。

    我认为问题是编译器无法准确地计算出您返回的内容(不,我也不确定为什么!),但如果您明确表示,我认为它会起作用。。。

    private async Task<Either<string, Unit>> DoMyStuffAsync() =>
      (await DoLibraryStuffAsync())
        .Match(_ => Right<string, Unit>(unit),
          ex => $"Ex: {ex.Message}");
    

    我希望有人能过来向我们两个解释为什么我们需要这样做,但至少这应该能让你继续前进。

    使现代化

    好吧,我和一个比我更了解这些东西的人讨论了这个问题(实际上大多数人都是这样),我想我知道为什么你会出现编译器错误。

    考虑以下愚蠢的方法。。。

    Either<string, int> Jim() {
      Random r = new();
      return r.Next() % 100 > 50 ? 1 : "jim";
    }
    

    这编译时无需显式转换为 Either 因为可以返回的两种类型都在相同的代码位中(即 return 陈述

    在您的代码中,两个 Funcs 你传给的 Match 是在不同的代码片段中,所以编译器无法将它们放在一起并计算出返回类型。我认为这是因为,尽管我们人类可以理解这两者 Func s通过 火柴 为相同的方法生成一个返回值,编译器并不知道。它不知道是什么 火柴 做

    不确定这是否完全清楚,但我认为它给出了一些想法,为什么您需要至少投射一个返回值。

        2
  •  0
  •   Guru Stron    2 年前

    我认为你应该考虑使用 ToEither (具有接受两者的版本 Try 和 TryAsync ):

    async Task<Either<string, Unit>> DoMyStuffAsync() =>
         await DoLibraryStuffAsync().ToEither(ex => $"Ex: {ex.Message}");