如何在C# LanguageExt库中链式绑定多个TryAsync monad?
问题解决
你代码编译失败的核心原因是提前对GetFolder执行了await操作:TryAsync<T>经过await后会得到Try<T>类型,无法直接绑定返回TryAsync的后续方法,去掉多余的await即可正常使用Bind链式调用。
正确的链式写法示例
GetFolder("123") .Bind(folder => CreateFolder("New folder", folder.Id)) .Bind(newFolderId => UploadFile(stream, "New file name.txt", "text/plain", newFolderId)) .Match( fileId => /* 处理上传成功返回的文件ID */, ex => /* 统一处理全链路所有环节抛出的异常 */ );
注意你原示例中
CreateFolder返回的是TryAsync<string>(文件夹ID),所以第二个Bind的入参是文件夹ID而非文件夹对象,对应参数名写错也可能导致编译报错。
方法返回值设计建议
方法本身直接返回TryAsync<T>更合理:
调用Google Drive API本身就是包含IO异常风险的异步操作,你可以在方法内部直接把API调用的逻辑包裹进TryAsync,自动捕获所有异常封装到monad中,调用方无需额外处理裸Task的异常,也不需要重复做TryAsync封装,更符合函数式编程隔离副作用的设计。
示例实现参考:
using LanguageExt; using static LanguageExt.Prelude; public TryAsync<File> GetFolder(string folderId) => TryAsync(async () => { // 此处为调用Google Drive API的真实逻辑,所有抛出的异常都会被自动捕获 return await driveService.Files.Get(folderId).ExecuteAsync(); });
可选的更易读写法
你也可以用LINQ查询语法拼接操作流,逻辑更直观:
var uploadOperation = from folder in GetFolder("123") from newFolderId in CreateFolder("New folder", folder.Id) from fileId in UploadFile(stream, "New file name.txt", "text/plain", newFolderId) select fileId; await uploadOperation.Match( Succ: id => /* 处理成功逻辑 */, Fail: ex => /* 处理异常逻辑 */ );
如果仍有编译报错,请先检查是否已经引入LanguageExt和LanguageExt.Prelude的命名空间引用。
内容的提问来源于stack exchange,提问作者Avrohom Yisroel
相关产品推荐
相关产品推荐

