如何使用LanguageExt EitherAsync返回非Error类型的Left值?
解决方案
你的问题出在对TryAsync的使用场景理解偏差,以及委托返回类型不统一导致的编译错误:
TryAsync的定位:它的核心作用是捕获异步操作中抛出的异常,并将异常转换为Either的Left值。但你的场景里,CardNotFound、CardLocked都是业务逻辑判断的结果,不属于异常,因此不需要用TryAsync来包裹。编译错误根源:你在
TryAsync的委托中,时而返回Task<TransactionRequestStates>,时而返回Card,返回类型完全不统一,编译器无法推断TryAsync的泛型参数,因此报错。
正确的异步实现方式
直接构建EitherAsync类型,通过业务判断返回对应的Left或Right:
private static EitherAsync<TransactionRequestStates, Card> GetCard(AppDbContext context, string cardSerialNumber) { return EitherAsync.FromTask(async () => { // 异步查询数据库 Card? card = await context.Cards.SingleOrDefaultAsync(c => c.SerialNumber == cardSerialNumber); // 业务逻辑判断 if (card == null) { return Left<TransactionRequestStates, Card>(TransactionRequestStates.CardNotFound); } if (card.Locked) { return Left<TransactionRequestStates, Card>(TransactionRequestStates.CardLocked); } // 其他有效性检查... // 所有检查通过,返回有效卡片 return Right<TransactionRequestStates, Card>(card); }); }
更简洁的写法(拆分异步方法与Either转换)
如果你习惯先写标准的异步Task方法,也可以将其转换为EitherAsync:
// 标准异步方法,返回Task<Either<...>> private static async Task<Either<TransactionRequestStates, Card>> GetCardCore(AppDbContext context, string cardSerialNumber) { Card? card = await context.Cards.SingleOrDefaultAsync(c => c.SerialNumber == cardSerialNumber); if (card == null) return TransactionRequestStates.CardNotFound; if (card.Locked) return TransactionRequestStates.CardLocked; // 其他检查... return card; } // 转换为EitherAsync供后续LINQ组合使用 private static EitherAsync<TransactionRequestStates, Card> GetCard(AppDbContext context, string cardSerialNumber) => GetCardCore(context, cardSerialNumber).ToEitherAsync();
这样实现后,你的Process方法中的LINQ查询就能正常组合这些异步方法,符合你预期的工作流。
内容的提问来源于stack exchange,提问作者Avrohom Yisroel
相关产品推荐
相关产品推荐

